From fc70aa66fc93f343396a1f0acb506e071b5749eb Mon Sep 17 00:00:00 2001 From: Justin Oros Date: Mon, 21 Sep 2026 22:32:53 -0700 Subject: [PATCH] Redesign loader card as three load options --- app.js | 8 +-- index.html | 54 ++++++++++++------- styles.css | 149 ++++++++++++++++++++++++++++++++++------------------- 3 files changed, 136 insertions(+), 75 deletions(-) diff --git a/app.js b/app.js index 72a1b73..432e578 100644 --- a/app.js +++ b/app.js @@ -7,6 +7,7 @@ const $ = (id) => document.getElementById(id); const els = { dropZone: $("dropZone"), + dropTarget: $("dropTarget"), loaderTitle: $("loaderTitle"), loaderStatus: $("loaderStatus"), browseBtn: $("browseBtn"), @@ -356,7 +357,7 @@ els.copyPathBtn.addEventListener("click", async () => { try { await navigator.clipboard.writeText(SAVES_PATH); - toast("Saves folder path copied. Paste it into the file dialog's address bar, then open your SteamID and save folders."); + toast("Path copied. Paste it into the file dialog's address bar, then open your SteamID and save folders."); } catch { toast("Couldn't copy. Select the path and copy it manually.", true); } @@ -393,8 +394,9 @@ els.dropZone.classList.remove("dragging"); loadFile(e.dataTransfer.files[0]); }); - els.dropZone.addEventListener("keydown", (e) => { - if (e.target === els.dropZone && (e.key === "Enter" || e.key === " ")) { + els.dropTarget.addEventListener("click", browse); + els.dropTarget.addEventListener("keydown", (e) => { + if (e.key === "Enter" || e.key === " ") { e.preventDefault(); browse(); } diff --git a/index.html b/index.html index 029d547..b30b021 100644 --- a/index.html +++ b/index.html @@ -19,27 +19,45 @@
-
-
-

Drop your SaveData.zip here

+
+
+

Load your save

No save loaded. You can browse and edit items, but saving needs a loaded save.

-
- - -
-
- Your save file is here - - - %USERPROFILE%\AppData\LocalLow\Endnight\SonsOfTheForest\Saves\SteamID\SinglePlayer\SaveID\SaveData.zip -

SteamID is the long number folder. SaveID is one folder per save; sort by date modified to find your latest. Hosted co-op saves are under Multiplayer folder instead of SinglePlayer.

-

Or let PowerShell find it for you. Close the game, open PowerShell and paste:

-
- irm https://raw.githubusercontent.com/JustinOros/sotf-inventory/main/Find-SaveData.ps1 | iex - + +
+
+ Option A +

Browse to your file

+

Your save is here:

+ %USERPROFILE%\AppData\LocalLow\Endnight\SonsOfTheForest\Saves\SteamID\SinglePlayer\SaveID\SaveData.zip +

SteamID is the long number folder. Pick the newest SaveID folder. Co-op host saves are in Multiplayer.

+
+ + +
+ +
+ +
+ Option B +

Use this PowerShell script

+

Close the game, open PowerShell and paste:

+ irm https://raw.githubusercontent.com/JustinOros/sotf-inventory/main/Find-SaveData.ps1 | iex +

Explorer opens with your latest SaveData.zip selected. Drag it onto this page.

+
+ +
+
+ +
+ Option C +

Drag and drop

+
+ + Drop your SaveData.zip here +
-

It opens Explorer with your latest SaveData.zip selected, ready to drag onto this page.

diff --git a/styles.css b/styles.css index ba4a0f4..4ed71a1 100644 --- a/styles.css +++ b/styles.css @@ -77,106 +77,146 @@ main { } .loader { - display: grid; - grid-template-columns: 1fr auto; - gap: 1rem 1.5rem; - align-items: center; - padding: 1.5rem; - border: 1px dashed var(--moss); + padding: 1.75rem; + border: 1px solid var(--line); border-radius: 4px; background: var(--spruce-2); - transition: border-color 0.15s, background 0.15s; } -.loader.dragging { - border-color: var(--bone); - border-style: solid; - background: var(--spruce-3); -} - -.loader.loaded { - border-style: solid; - border-color: var(--line); -} - -.loader h2 { +.loader-head h2 { font-family: var(--display); font-weight: 400; - font-size: 1.75rem; + font-size: 1.9rem; margin: 0; } -.loader p { +.loader-head p { margin: 0.25rem 0 0; color: var(--fog); } -.path-hint { - grid-column: 1 / -1; +.loader.loaded .loader-head h2 { color: #fff; } + +.options { display: grid; - gap: 0.4rem; - justify-items: start; - font-size: 0.875rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1.25rem; + margin-top: 1.5rem; +} + +.option { + display: flex; + flex-direction: column; + gap: 0.6rem; + padding: 1.25rem; + background: var(--spruce); + border: 1px solid var(--line); + border-radius: 4px; +} + +.option-tag { + font-size: 0.8rem; + font-weight: 600; + color: var(--moss); +} + +.option h3 { + font-family: var(--display); + font-weight: 400; + font-size: 1.4rem; + line-height: 1.2; + margin: -0.35rem 0 0.2rem; +} + +.option p { + margin: 0; color: var(--fog); - padding-top: 1rem; - border-top: 1px solid var(--line); + font-size: 0.925rem; +} + +.option .hint { + font-size: 0.85rem; + line-height: 1.5; +} + +.option-actions { + display: flex; + flex-wrap: wrap; + gap: 1rem; + align-items: center; + margin-top: auto; + padding-top: 0.4rem; } .path { display: block; - width: 100%; font-family: Consolas, "Courier New", monospace; - font-size: 0.95rem; + font-size: 0.8rem; + line-height: 1.55; color: var(--bone); - background: var(--spruce); + background: var(--spruce-2); border: 1px solid var(--line); border-radius: 3px; - padding: 0.6rem 0.75rem; - overflow-wrap: anywhere; + padding: 0.55rem 0.7rem; + overflow-wrap: break-word; user-select: all; } -.path-hint var { +.option var { font-style: normal; color: #e0a39a; - border-bottom: 1px dotted var(--blood-hi); -} - -.path-label { - display: flex; - align-items: baseline; - gap: 0.35rem; } .copy-btn { display: inline-flex; align-items: center; - gap: 0.3rem; - padding: 0; + gap: 0.4rem; text-decoration: none; } -.copy-btn span { +.btn-link.copy-btn { padding: 0; } + +.copy-btn svg { flex: none; } + +.btn.copy-btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + +.btn-link.copy-btn span { text-decoration: underline; text-underline-offset: 3px; } -.copy-btn svg { position: relative; top: 1px; } +.option-drop { + cursor: pointer; +} -.cmd { +.drop-well { + flex: 1; display: flex; - gap: 0.75rem; + flex-direction: column; align-items: center; - width: 100%; + justify-content: center; + gap: 0.75rem; + min-height: 11rem; + text-align: center; + color: var(--fog); + border: 2px dashed var(--moss); + border-radius: 4px; + transition: border-color 0.15s, background 0.15s, color 0.15s; } -.cmd .path { flex: 1; } - -.path-note { - margin: 0; - max-width: 60em; +.option-drop:hover .drop-well, +.loader.dragging .drop-well { + border-color: var(--bone); + color: var(--bone); + background: var(--spruce-3); } +.loader.dragging { border-color: var(--moss); } + .btn { font: 600 1rem var(--body); color: var(--bone); @@ -469,7 +509,8 @@ dialog p { margin: 0 0 0.9rem; line-height: 1.55; } @media (max-width: 720px) { .hero { padding: 2.5rem 1rem 5.5rem; } main { padding: 1.5rem 1rem 0; } - .loader { grid-template-columns: 1fr; } + .options { grid-template-columns: 1fr; } + .drop-well { min-height: 7rem; } .col-cat, .cell-cat, .col-id, .cell-id { display: none; } .col-count { width: auto; } .stepper input { width: 4rem; }