feat(web): admin area with instance default theme, custom logo/favicon; .theme.json export
- Admin settings tab (admin-only) now holds user management plus a server-wide default theme editor (live preview + discard) and logo/favicon branding. - New singleton InstanceSettings model + /api/instance router (public GET for the login screen; admin-gated theme PUT and logo/favicon upload/delete, reusing the avatar PIL/validation pattern). - Instance default theme is the base users inherit and the target a per-colour "Reset" returns to (baseColor: instance default -> built-in). - Custom favicon overrides the primary-colour tinting; custom logo replaces the top-left glyph+text, hard-capped so it only scales down and never breaks layout. Branding + defaults load before login (public endpoint). - Theme export now uses the recognised .theme.json extension (old .theme still imports); import stays partial/unknown-key aware. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1390,6 +1390,26 @@ a { color: var(--primary); text-decoration: none; }
|
||||
font-size: 12px; font-weight: 700; text-decoration: none;
|
||||
}
|
||||
.theme-io-help:hover { background: var(--hover-highlight); color: var(--text-1); }
|
||||
|
||||
/* Custom instance logo (replaces the glyph+text). Hard-capped so it can only
|
||||
scale DOWN and never pushes the topbar/auth layout. */
|
||||
.topbar-logo-img { max-height: 40px; max-width: 150px; width: auto; height: auto; object-fit: contain; display: block; }
|
||||
.auth-logo-img { max-height: 56px; max-width: 220px; width: auto; height: auto; object-fit: contain; display: block; }
|
||||
|
||||
/* Admin panel: default-theme editor + branding */
|
||||
.admin-theme-grid { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
|
||||
.admin-theme-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px; }
|
||||
.admin-theme-name { font-size: 13px; color: var(--text-2); }
|
||||
.admin-theme-actions { display: flex; gap: 8px; margin-top: 14px; }
|
||||
.admin-brand-row { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
|
||||
.admin-brand-label { width: 70px; font-size: 13px; color: var(--text-2); }
|
||||
.admin-brand-preview {
|
||||
width: 48px; height: 48px; flex-shrink: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
background: var(--bg-hover); border-radius: var(--radius-sm); overflow: hidden;
|
||||
}
|
||||
.admin-brand-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
|
||||
.admin-brand-none { font-size: 10px; color: var(--text-3); text-align: center; padding: 2px; }
|
||||
.settings-table-section {
|
||||
font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
|
||||
color: var(--text-3); margin: 18px 0 6px; padding: 0 2px;
|
||||
|
||||
Reference in New Issue
Block a user