diff --git a/containers/libreportal/frontend/core/setup/css/setup-wizard.css b/containers/libreportal/frontend/core/setup/css/setup-wizard.css
index 746fad9..dacc61a 100755
--- a/containers/libreportal/frontend/core/setup/css/setup-wizard.css
+++ b/containers/libreportal/frontend/core/setup/css/setup-wizard.css
@@ -1372,6 +1372,16 @@ body.setup-wizard-open .custom-select-popup { z-index: 10001; }
flex-shrink: 0;
}
+/* Fills that same slot. Muted by default so the row reads name-first, and it
+ picks up the accent with the rest of the card on hover. */
+.setup-storage-icon {
+ width: 20px;
+ height: 20px;
+ flex-shrink: 0;
+ color: rgba(var(--text-rgb), 0.55);
+}
+.setup-storage-card:hover .setup-storage-icon { color: var(--accent); }
+
/* Divider between "where apps go regardless" and "what you can opt into". */
.setup-storage-divider {
display: flex;
diff --git a/containers/libreportal/frontend/core/setup/js/setup-wizard.js b/containers/libreportal/frontend/core/setup/js/setup-wizard.js
index b0ff706..d251c35 100755
--- a/containers/libreportal/frontend/core/setup/js/setup-wizard.js
+++ b/containers/libreportal/frontend/core/setup/js/setup-wizard.js
@@ -570,6 +570,27 @@ class SetupWizard {
return s.mount && s.mount !== '/' ? s.mount : (s.path || 'Default location');
}
+ // The 20px slot in these cards exists to line them up with the app cards,
+ // which carry an icon — so it was reserving room for a picture and then
+ // showing nothing. Inline SVG rather than an asset: one glyph each, stroked
+ // in currentColor so it follows the theme.
+ _cardIcon(kind) {
+ const svg = (d) => ``;
+ switch (kind) {
+ case 'cloud': // S3, B2 — someone else's disk
+ return svg('