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(''); + case 'server': // SFTP — a machine you can name + return svg(''); + case 'peer': // another LibrePortal + return svg(''); + case 'disk': + default: // a local drive + return svg(''); + } + } + _storageCard(c, key, opts) { const o = opts || {}; const refused = c.verdict === 'refuse'; @@ -582,7 +603,7 @@ class SetupWizard { return `
- + ${this._cardIcon('disk')} ${this.escapeHtml(title)} ${badge} @@ -797,7 +818,7 @@ class SetupWizard { : `${this.escapeHtml(l.type.toUpperCase())} \u00b7 ${this.escapeHtml(l.ssh_host || l.host || '')}`; return `
- + ${this._cardIcon(l.type === 'local' ? 'disk' : (l.type === 'sftp' ? 'server' : (l.type === 'peer' ? 'peer' : 'cloud')))} ${this.escapeHtml(l.name)} ${badge} ${warn} ${this.escapeHtml(where)} @@ -815,12 +836,9 @@ class SetupWizard { const add = box.querySelector('#sw-backup-add'); if (add) add.addEventListener('click', () => this.showBackupDestModal(-1)); - if (note) { - const offsite = this.backupLocations.some(l => l.type !== 'local'); - note.innerHTML = offsite - ? '' - : 'Everything here is on this machine. That protects against deletions and bad updates \u2014 but not against losing the machine. Add an SFTP or S3 destination for that.'; - } + // No standing note here. The cards already say where each destination is, + // and a paragraph that never changes is furniture. + if (note) note.innerHTML = ''; } // Add or edit a destination. Local wants a path; everything else wants