Show app icon in brand when no org logo is configured

Matches the timesheet app: the blue squircle reimburse icon appears
next to the org name instead of the initials fallback. Uses var(--accent)
fill so it adapts to dark mode. Also used as fallback if logo image fails.

https://claude.ai/code/session_01JyuActqTJG5tuRQNLmT7fZ
This commit is contained in:
Claude 2026-06-08 15:42:50 +00:00
parent b1efad2ab4
commit c9f114d52c
No known key found for this signature in database

View file

@ -141,8 +141,7 @@ body{
.kb-brand{display:flex;align-items:center;gap:14px;min-width:0;}
.kb-brand .logo{
height:46px;width:46px;flex:0 0 46px;border-radius:10px;
display:grid;place-items:center;background:var(--accent-soft);
color:var(--accent);font-weight:800;font-size:18px;overflow:hidden;
display:grid;place-items:center;overflow:hidden;
}
.kb-brand .logo img{width:100%;height:100%;object-fit:contain;}
.kb-brand .org{font-size:17px;font-weight:700;color:var(--text);letter-spacing:-0.01em;}
@ -691,6 +690,15 @@ function makeSelect(options, value, onChange, placeholder) {
}
// ========== FORM RENDERING ==========
function appIconSVG() {
const s = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
s.setAttribute('viewBox', '0 0 48 48');
s.setAttribute('aria-hidden', 'true');
s.style.cssText = 'width:100%;height:100%;display:block;';
s.innerHTML = `<rect width="48" height="48" rx="12" fill="var(--accent)"/><rect x="7.5" y="14" width="33" height="20" rx="3.2" fill="none" stroke="#fff" stroke-width="2.8"/><circle cx="24" cy="24" r="4.6" fill="none" stroke="#fff" stroke-width="2.6"/><path d="M12.7 21.4V26.6M35.3 21.4V26.6" stroke="#fff" stroke-width="2.6" stroke-linecap="round"/>`;
return s;
}
function render() {
const app = $('#app');
app.innerHTML = '';
@ -762,14 +770,12 @@ function render() {
img.src = 'assets/logo.png';
img.onerror = function() {
this.src = 'assets/logo.jpg';
this.onerror = function() {
this.replaceWith(document.createTextNode((CFG.organization || 'ORG').slice(0,2).toUpperCase()));
};
this.onerror = function() { this.replaceWith(appIconSVG()); };
};
if (CFG['logo-maxwidth']) img.style.maxWidth = CFG['logo-maxwidth'] * 28.3465 + 'px';
logoBox.appendChild(img);
} else {
logoBox.textContent = (CFG.organization || 'ORG').slice(0,2).toUpperCase();
logoBox.appendChild(appIconSVG());
}
const orgSpan = el('span', {className:'org'}, CFG.organization || '');
orgSpan.appendChild(el('small', null, 'Expense reimbursement'));