Match toolbar to invoice app

- kb-iconbtn 34px → 32px
- kb-seg button padding 6px 11px → 5px 10px
- Add kb-seg button:disabled rule
- toolbar margin-bottom 16px → 18px
- Language select uses .kb-select class with width:auto (remove .kb-toolbar select rule)
- Size seg: A−/A+ only with live % label, stepped scale array, buttons disable at limits

https://claude.ai/code/session_01JyuActqTJG5tuRQNLmT7fZ
This commit is contained in:
Claude 2026-06-08 16:12:33 +00:00
parent f4eb0e7e4a
commit 15ffddb57b
No known key found for this signature in database

View file

@ -115,7 +115,7 @@ body{
.kb-wrap{max-width:980px;margin:0 auto;padding:24px 20px 56px;}
/* ── Toolbar ──────────────────────────────────────────────────────────────── */
.kb-toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:16px;}
.kb-toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:18px;}
.kb-toolbar .spacer{flex:1;}
.kb-seg{
display:inline-flex;align-items:center;gap:2px;
@ -125,12 +125,13 @@ body{
.kb-seg button{
font:600 var(--fs-small)/1 var(--font-sans);color:var(--text-muted);
background:transparent;border:0;white-space:nowrap;
padding:6px 11px;border-radius:4px;cursor:pointer;
padding:5px 10px;border-radius:4px;cursor:pointer;
}
.kb-seg button.is-active{background:var(--accent-soft);color:var(--accent);}
.kb-seg button:hover:not(.is-active){color:var(--text);}
.kb-seg button:hover:not(.is-active):not(:disabled){color:var(--text);}
.kb-seg button:disabled{opacity:.4;cursor:not-allowed;}
.kb-iconbtn{
display:inline-grid;place-items:center;width:34px;height:34px;
display:inline-grid;place-items:center;width:32px;height:32px;
background:var(--surface);border:1px solid var(--border);
border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;
}
@ -338,18 +339,6 @@ body{
/* ── App wordmark (toolbar left) ──────────────────────────────────────────── */
.kb-doctitle h1{display:inline-flex;align-items:center;gap:9px;}
.kb-doctitle h1 svg{flex-shrink:0;}
/* Language select in toolbar */
.kb-toolbar select{
font:600 var(--fs-small)/1 var(--font-sans);color:var(--text-muted);
background:var(--surface);border:1px solid var(--border);
border-radius:var(--radius-sm);padding:5px 28px 5px 10px;
outline:none;appearance:none;cursor:pointer;
background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 16 16' fill='none' stroke='%235F6975' stroke-width='1.8'><path d='M4 6l4 4 4-4'/></svg>");
background-repeat:no-repeat;background-position:right 8px center;
transition:border-color .14s,color .14s;
}
.kb-toolbar select:focus{border-color:var(--accent);box-shadow:var(--ring);color:var(--text);}
.kb-toolbar select:hover{border-color:var(--accent-border);color:var(--text);}
/* ── Loading ──────────────────────────────────────────────────────────────── */
.kb-loading{text-align:center;padding:80px;color:var(--text-muted);}
@ -717,7 +706,7 @@ function render() {
// Language selector (only when CFG.languages has >1 entry) — goes first
if (Array.isArray(CFG.languages) && CFG.languages.length > 1) {
const langSel = el('select', {'aria-label':'Language'});
const langSel = el('select', {className:'kb-select', 'aria-label':'Language', style:'width:auto;padding:5px 28px 5px 8px;font-size:var(--fs-small)'});
CFG.languages.forEach(lang => {
const code = typeof lang === 'object' ? lang.code : lang;
const name = typeof lang === 'object' ? lang.name : lang;
@ -728,20 +717,24 @@ function render() {
toolbar.appendChild(el('div', {className:'spacer'}));
// Font size
// Font size — A / A+ with a live % label
const scales = [0.8, 0.9, 1, 1.12, 1.25];
let scaleIdx = 2; // default: 100%
const szLabel = el('span', {style:'font-size:12px;color:var(--text-muted);font-family:var(--font-mono)'}, '100%');
const sizeSeg = el('div', {className:'kb-seg', role:'group', 'aria-label':'Text size'});
const sizeOpts = [{lbl:'A', scale:0.9}, {lbl:'A', scale:1}, {lbl:'A+', scale:1.12}];
let activeSizeIdx = 1;
sizeOpts.forEach((s, i) => {
const btn = el('button', {type:'button', className: i === activeSizeIdx ? 'is-active' : ''}, s.lbl);
btn.addEventListener('click', () => {
$$('button', sizeSeg).forEach(b => b.classList.remove('is-active'));
btn.classList.add('is-active');
document.documentElement.style.setProperty('--font-scale', s.scale);
});
sizeSeg.appendChild(btn);
});
const szDown = el('button', {type:'button', 'aria-label':'Smaller text'}, 'A');
const szUp = el('button', {type:'button', 'aria-label':'Larger text'}, 'A+');
function applyScale() {
szDown.disabled = scaleIdx === 0;
szUp.disabled = scaleIdx === scales.length - 1;
document.documentElement.style.setProperty('--font-scale', scales[scaleIdx]);
szLabel.textContent = Math.round(scales[scaleIdx] * 100) + '%';
}
szDown.addEventListener('click', () => { if (scaleIdx > 0) { scaleIdx--; applyScale(); } });
szUp.addEventListener('click', () => { if (scaleIdx < scales.length-1) { scaleIdx++; applyScale(); } });
sizeSeg.append(szDown, szUp);
toolbar.appendChild(sizeSeg);
toolbar.appendChild(szLabel);
// Theme toggle (single icon button: moon = light mode, sun = dark mode)
const themeBtn = el('button', {className:'kb-iconbtn', type:'button', 'aria-label':'Toggle theme'});