style(assistant): компактные режимы — иконка + короткая подпись

Кнопки режимов перерисованы как тулбар: вертикально иконка (inline SVG .ic) +
лаконичная подпись. Длинные ярлыки сокращены (Проверить решение -> Проверить,
Тест в банк -> В банк, Нарисовать -> Рисунок); полный смысл в title. Рендер
data-driven из MODE_DEFS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-24 22:54:19 +03:00
parent ee740817a8
commit b310029e8d
+18 -10
View File
@@ -358,10 +358,13 @@
'.asst-msg-assistant .asst-rich{color:#28324a;}',
'.asst-msg-ph{opacity:.6;}',
'.asst-msg-links{align-self:flex-start;font-size:.74rem;}',
'.asst-modes{display:flex;gap:6px;margin:2px 0 8px;}',
'.asst-mode{flex:1;border:1px solid #e6e3f2;background:#faf9fd;border-radius:9px;padding:6px 6px;font:700 .68rem Manrope,sans-serif;color:#64748b;cursor:pointer;transition:all .14s;}',
'.asst-mode:hover{border-color:#9B5DE5;color:#9B5DE5;}',
'.asst-mode.on{background:linear-gradient(135deg,#9B5DE5,#7d3fc8);border-color:transparent;color:#fff;box-shadow:0 3px 9px rgba(155,93,229,.32);}',
'.asst-modes{display:flex;gap:5px;margin:2px 0 9px;}',
'.asst-mode{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;border:1px solid #ece9f6;background:#faf9fd;border-radius:11px;padding:7px 3px;font:700 .6rem Manrope,sans-serif;color:#64748b;cursor:pointer;transition:all .14s;}',
'.asst-mode .ic{width:15px;height:15px;opacity:.85;}',
'.asst-mode span{white-space:nowrap;}',
'.asst-mode:hover{border-color:#cdbdf2;color:#7e3eca;background:#fff;}',
'.asst-mode.on{background:linear-gradient(135deg,#9B5DE5,#7d3fc8);border-color:transparent;color:#fff;box-shadow:0 4px 11px rgba(155,93,229,.3);}',
'.asst-mode.on .ic{opacity:1;}',
'.asst-src{align-self:flex-start;font-size:.72rem;color:#8a94a6;}',
'.asst-src a{color:#7e3eca;font-weight:700;text-decoration:none;}',
'.asst-fb{align-self:flex-start;display:flex;gap:6px;}',
@@ -556,6 +559,14 @@
var FB_UP = '<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 10v11"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/></svg>';
var FB_DOWN = '<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="transform:rotate(180deg)"><path d="M7 10v11"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/></svg>';
var MODE_PH = { answer: 'Спроси что угодно: «объясни…», «как…»', hint: 'Задача, по которой нужна подсказка…', check: 'Вставь своё решение — проверю…', draw: 'Опиши картинку: «кот-учёный, плоская иллюстрация»', quiz: 'Тема или текст — сгенерирую вопросы для банка' };
var _svg = function (p) { return '<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' + p + '</svg>'; };
var MODE_DEFS = [
{ m: 'answer', label: 'Ответ', title: 'Ответить на вопрос', ic: _svg('<path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/>') },
{ m: 'hint', label: 'Подсказка', title: 'Подсказать, не решая целиком', ic: _svg('<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>') },
{ m: 'check', label: 'Проверить', title: 'Проверить твоё решение', ic: _svg('<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>') },
{ m: 'quiz', label: 'В банк', title: 'Сгенерировать вопросы в банк', ic: _svg('<rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M12 11h4"/><path d="M12 16h4"/><path d="M8 11h.01"/><path d="M8 16h.01"/>'), tch: true },
{ m: 'draw', label: 'Рисунок', title: 'Нарисовать картинку', ic: _svg('<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21"/>') }
];
function openAsk(prefill) {
var sel = _lastSel, pc = getPageContext();
var noun = pc && pc.kind === 'lesson' ? 'этот урок' : 'этот параграф';
@@ -569,12 +580,9 @@
var chips = '<div class="asst-chips">' + ctxBtns +
sug.map(function (q) { return '<button class="asst-chip" type="button">' + esc(q) + '</button>'; }).join('') + '</div>';
var isTch = (_role === 'teacher' || _role === 'admin');
var modes = '<div class="asst-modes">' +
'<button class="asst-mode on" data-m="answer">Ответ</button>' +
'<button class="asst-mode" data-m="hint">Подсказка</button>' +
'<button class="asst-mode" data-m="check">Проверить решение</button>' +
(isTch ? '<button class="asst-mode" data-m="quiz">Тест в банк</button>' : '') +
'<button class="asst-mode" data-m="draw">Нарисовать</button></div>';
var modes = '<div class="asst-modes">' + MODE_DEFS.filter(function (d) { return !d.tch || isTch; })
.map(function (d) { return '<button class="asst-mode' + (d.m === 'answer' ? ' on' : '') + '" data-m="' + d.m + '" title="' + d.title + '">' + d.ic + '<span>' + d.label + '</span></button>'; })
.join('') + '</div>';
openBubble(
'<div class="asst-name"><span class="asst-name-face">' + faceSVG('happy') + '</span>Спроси Квантика' +
'<button class="asst-link" data-a="mem" style="float:right;font-weight:600;margin-right:24px">Память</button>' +