diff --git a/public/css/assistant.css b/public/css/assistant.css index f86cbdd0..32417de5 100644 --- a/public/css/assistant.css +++ b/public/css/assistant.css @@ -396,7 +396,18 @@ body.assistant-workspace #assistant-chat-view { min-height: 0; } /* Composer model pill (Open WebUI-style, its own line above the actions) */ .assistant-model-pill { display:flex; align-items:center; } .assistant-model-pill[hidden] { display:none; } -.assistant-model-control { border:1px solid var(--g200); background:white; border-radius:999px; padding:3px 10px; font-size:11px; color:var(--g600); cursor:pointer; max-width:220px; } +/* Model choice reads as a control, not a raw form element: the native chevron is + replaced with one that matches the composer, and the whole pill responds. */ +.assistant-model-control { appearance:none; -webkit-appearance:none; border:1px solid var(--g200); background:white; border-radius:999px; padding:5px 26px 5px 11px; font-family:inherit; font-size:11.5px; font-weight:600; color:var(--g600); cursor:pointer; max-width:240px; text-overflow:ellipsis; box-shadow:var(--shadow); + background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M6 8.2 2.4 4.6l.8-.8L6 6.6l2.8-2.8.8.8z'/%3E%3C/svg%3E"); + background-repeat:no-repeat; background-position:right 9px center; background-size:10px; transition:border-color .12s ease, color .12s ease, background-color .12s ease; } +.assistant-model-control:hover { border-color:var(--blue-light); background-color:var(--blue-light); color:var(--blue); } +.assistant-model-control:focus-visible { outline:none; border-color:var(--blue); box-shadow:0 0 0 3px var(--blue-light); } +.assistant-model-control option { font-weight:500; color:var(--g800); background:white; } +/* The image-model select sits in a popup, where a full-width control reads + better than a pill. */ +.assistant-create-image-label { display:block; font-size:11px; font-weight:700; color:var(--g500); text-transform:uppercase; letter-spacing:.04em; margin:10px 0 4px; } +#assistant-image-model-select { max-width:100%; width:100%; border-radius:10px; padding:8px 26px 8px 11px; font-size:12.5px; } .assistant-model-pick { display:block; } /* Send button becomes a red stop while the assistant works */ .btn-send.busy { background:var(--danger,#dc2626); } diff --git a/test/assistant-component-css.test.js b/test/assistant-component-css.test.js index 0b85c577..6f9aa498 100644 --- a/test/assistant-component-css.test.js +++ b/test/assistant-component-css.test.js @@ -178,3 +178,24 @@ test('the advertised New chat shortcut actually works, and only inside the assis assert.match(handler, /classList\.contains\('assistant-workspace'\)/); assert.match(handler, /btn-assistant-clear/); }); + +test('the admin panel stays usable on a phone', () => { + const fs = require('node:fs'); + const path = require('node:path'); + const root = path.join(__dirname, '..'); + const css = fs.readFileSync(path.join(root, 'public/css/styles.css'), 'utf8'); + // Admin rows are a 3-column grid on desktop; on a phone they must stack or the + // label column squeezes every control into an unusable sliver. + const mobile = css.slice(css.indexOf('@media (max-width:640px) {', css.indexOf('.admin-row {'))); + assert.match(mobile, /\.admin-row \{ grid-template-columns:1fr; \}/, 'rows stack'); + assert.match(mobile, /\.admin-control \{ max-width:none; \}/, 'controls use the full width'); + + // Every block added inside a row must be able to shrink, or it forces the + // grid cell wider than the screen and the page scrolls sideways. + const html = fs.readFileSync(path.join(root, 'public/components/admin.html'), 'utf8'); + const rowChildren = html.split('\n').filter(l => l.includes('style="flex:1;display:flex')); + assert.ok(rowChildren.length > 0, 'found the flex blocks inside admin rows'); + for (const line of rowChildren) { + assert.match(line, /min-width:0/, 'a flex child inside an admin row must be shrinkable: ' + line.trim().slice(0, 60)); + } +});