From b6c08f1b162f1e8f635e20000fda8355384692a6 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Wed, 24 Jun 2026 22:13:02 +0300 Subject: [PATCH] =?UTF-8?q?style(assistant):=20=D0=BF=D1=80=D0=B5=D0=BC?= =?UTF-8?q?=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D0=B9=D0=BD=20=D0=BE=D0=BA=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=9A=D0=B2=D0=B0=D0=BD=D1=82=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Окно «Спроси Квантика» — удобнее, красивее, солиднее: - шире (418px), многослойная мягкая тень с фиолетовым отливом, скругление 20px; - настоящая шапка с аватаром в круге (градиентный фон) и разделителем; - пузыри сообщений: ученик — фиолетовый градиент с хвостиком, ассистент — светлая карточка с тонкой рамкой; мягкая тень; - поле ввода с фокус-кольцом + отдельная кнопка отправки (стрелка-самолётик), градиентная — удобнее на телефоне и нагляднее; - режимы и чипы — мягкие пилюли, активный режим градиентный с тенью; - область чата выше (54vh) с аккуратным фиолетовым скроллбаром. Только frontend/js/assistant.js, без эмодзи (inline SVG). Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/js/assistant.js | 44 +++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/frontend/js/assistant.js b/frontend/js/assistant.js index 1df7e8c..58c1ea5 100644 --- a/frontend/js/assistant.js +++ b/frontend/js/assistant.js @@ -285,17 +285,17 @@ '.asst-name-face{display:inline-block;transition:transform .2s;}', reduceMotion ? '' : '.asst-name-face.asst-think{animation:asstThink 1.3s ease-in-out infinite;transform-origin:60% 70%;}', '@keyframes asstThink{0%,100%{transform:scale(1) rotate(0);}50%{transform:scale(1.08) rotate(-4deg);}}', - '.asst-bubble{position:absolute;left:0;bottom:66px;width:380px;max-width:92vw;background:#fff;border-radius:18px;', - ' box-shadow:0 20px 56px rgba(15,23,42,.24);padding:15px 17px;border:1px solid rgba(15,23,42,.07);', + '.asst-bubble{position:absolute;left:0;bottom:66px;width:418px;max-width:94vw;background:#fff;border-radius:20px;', + ' box-shadow:0 28px 70px -16px rgba(76,29,149,.36),0 6px 20px rgba(15,23,42,.1),0 0 0 1px rgba(155,93,229,.1);padding:14px 16px 16px;border:none;', ' opacity:0;transform:translateY(8px) scale(.98);pointer-events:none;transition:opacity .18s,transform .18s;transform-origin:bottom left;}', - '.asst-name-face{display:inline-block;width:20px;height:20px;vertical-align:-4px;margin-right:7px;}', - '.asst-name-face svg{width:100%;height:100%;display:block;}', + '.asst-name-face{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;vertical-align:middle;border-radius:50%;background:linear-gradient(135deg,rgba(155,93,229,.18),rgba(6,182,212,.15));margin-right:10px;box-shadow:inset 0 0 0 1px rgba(155,93,229,.22);}', + '.asst-name-face svg{width:25px;height:25px;display:block;}', '.asst-memnote{font-size:.66rem;color:#9aa5b4;margin-top:9px;line-height:1.45;border-top:1px solid rgba(15,23,42,.05);padding-top:8px;}', '.asst-bubble.open{opacity:1;transform:translateY(0);pointer-events:auto;}', - '.asst-x{position:absolute;top:8px;right:8px;width:26px;height:26px;border:none;background:transparent;color:#8a94a6;', - ' cursor:pointer;border-radius:7px;font-size:18px;line-height:1;}', + '.asst-x{position:absolute;top:12px;right:12px;width:28px;height:28px;border:none;background:transparent;color:#94a3b8;z-index:3;', + ' cursor:pointer;border-radius:8px;font-size:19px;line-height:1;transition:all .14s;}', '.asst-x:hover{background:rgba(15,23,42,.06);color:#0F172A;}', - '.asst-name{font-size:.7rem;font-weight:800;color:#9B5DE5;text-transform:uppercase;letter-spacing:.03em;margin-bottom:6px;}', + '.asst-name{font-size:.98rem;font-weight:800;color:#0F172A;text-transform:none;letter-spacing:0;margin:-2px 0 11px;padding:0 28px 11px 0;border-bottom:1px solid rgba(15,23,42,.07);line-height:34px;}', '.asst-text{font-size:.86rem;line-height:1.5;color:#28324a;margin-bottom:12px;white-space:pre-line;}', '.asst-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;}', '.asst-btn{display:inline-flex;align-items:center;gap:6px;padding:7px 13px;border-radius:99px;border:none;cursor:pointer;', @@ -303,7 +303,13 @@ '.asst-btn:hover{background:#7e3eca;}', '.asst-link{background:none;border:none;color:#8a94a6;cursor:pointer;font:600 .76rem Manrope,sans-serif;padding:4px 2px;text-decoration:none;}', '.asst-link:hover{color:#9B5DE5;}', - '.asst-ask-in{width:100%;box-sizing:border-box;padding:9px 12px;border:1px solid #e2e8f0;border-radius:10px;font:inherit;font-size:.84rem;margin-bottom:10px;}', + '.asst-ask-row{display:flex;gap:8px;align-items:center;margin-bottom:4px;}', + '.asst-ask-in{flex:1;min-width:0;box-sizing:border-box;padding:11px 14px;border:1.5px solid #e6e3f2;border-radius:13px;font:inherit;font-size:.85rem;background:#faf9fd;transition:border-color .15s,box-shadow .15s,background .15s;}', + '.asst-ask-in:focus{outline:none;border-color:#9B5DE5;background:#fff;box-shadow:0 0 0 3px rgba(155,93,229,.13);}', + '.asst-send{flex-shrink:0;width:42px;height:42px;border:none;border-radius:13px;background:linear-gradient(135deg,#9B5DE5,#7d3fc8);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .12s,box-shadow .15s;box-shadow:0 4px 14px rgba(155,93,229,.32);}', + '.asst-send:hover{transform:translateY(-1px);box-shadow:0 7px 18px rgba(155,93,229,.42);}', + '.asst-send:active{transform:translateY(0);}', + '.asst-send svg{width:19px;height:19px;}', '.asst-ans{font-size:.82rem;line-height:1.5;color:#28324a;border-top:1px solid rgba(15,23,42,.06);padding:9px 0;}', '.asst-ans:first-of-type{border-top:none;}', '.asst-ans-q{font-weight:700;color:#0F172A;margin-bottom:2px;}', @@ -311,7 +317,7 @@ '.asst-ans-sec{font-size:.66rem;font-weight:800;color:#8a94a6;text-transform:uppercase;letter-spacing:.03em;margin:12px 0 2px;}', '.asst-ans-box{max-height:46vh;overflow:auto;}', '.asst-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px;}', - '.asst-chip{border:1px solid #e2e8f0;background:#f8fafc;border-radius:99px;padding:5px 10px;font:600 .72rem Manrope,sans-serif;color:#475569;cursor:pointer;text-align:left;}', + '.asst-chip{border:1px solid #e6e3f2;background:#faf9fd;border-radius:99px;padding:6px 12px;font:600 .72rem Manrope,sans-serif;color:#475569;cursor:pointer;text-align:left;transition:all .14s;}', '.asst-chip:hover{border-color:#9B5DE5;color:#9B5DE5;}', '.asst-chip-ctx{background:rgba(155,93,229,.1);border-color:rgba(155,93,229,.35);color:#7e3eca;}', '.asst-rich{font-size:.84rem;line-height:1.55;color:#28324a;}', @@ -330,17 +336,21 @@ '.asst-streaming::after{content:"";display:inline-block;width:2px;height:1em;vertical-align:-2px;margin-left:2px;background:#9B5DE5;animation:asst-blink 1s steps(2) infinite;}', '@keyframes asst-blink{50%{opacity:0;}}', '.asst-md-h{font-weight:800;color:#0F172A;margin:6px 0 2px;}', - '.asst-chat{max-height:46vh;overflow:auto;display:flex;flex-direction:column;gap:8px;margin-bottom:8px;}', + '.asst-chat{max-height:54vh;overflow:auto;display:flex;flex-direction:column;gap:9px;margin-bottom:10px;padding-right:5px;}', + '.asst-chat::-webkit-scrollbar{width:7px;}', + '.asst-chat::-webkit-scrollbar-thumb{background:rgba(155,93,229,.28);border-radius:99px;}', + '.asst-chat::-webkit-scrollbar-track{background:transparent;}', '.asst-chat:empty{display:none;}', - '.asst-msg{font-size:.84rem;line-height:1.5;border-radius:12px;padding:8px 11px;max-width:92%;word-break:break-word;}', - '.asst-msg-user{align-self:flex-end;background:#9B5DE5;color:#fff;}', - '.asst-msg-assistant{align-self:flex-start;background:rgba(15,23,42,.05);max-width:100%;}', + '.asst-msg{font-size:.85rem;line-height:1.55;border-radius:15px;padding:9px 13px;max-width:88%;word-break:break-word;box-shadow:0 1px 3px rgba(15,23,42,.06);}', + '.asst-msg-user{align-self:flex-end;background:linear-gradient(135deg,#9B5DE5,#7d3fc8);color:#fff;border-bottom-right-radius:5px;}', + '.asst-msg-assistant{align-self:flex-start;background:#f6f4fc;border:1px solid rgba(155,93,229,.1);max-width:100%;border-bottom-left-radius:5px;}', '.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 #e2e8f0;background:#f8fafc;border-radius:8px;padding:5px 6px;font:700 .68rem Manrope,sans-serif;color:#475569;cursor:pointer;}', - '.asst-mode.on{background:#9B5DE5;border-color:#9B5DE5;color:#fff;}', + '.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-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;}', @@ -558,7 +568,8 @@ '' + (_chat.length ? '' : '') + '' + '
' + chips + modes + - '' + + '
' + + '
' + '
Я помню последние ~6 сообщений этого разговора — как рабочая память: что было раньше, понимаю; старое постепенно забывается. «Очистить» — начать с чистого листа.
', {}); var inp = bubble.querySelector('.asst-ask-in'); var chatEl = bubble.querySelector('.asst-chat'); @@ -569,6 +580,7 @@ // свободный вопрос (context не задан явно) → подмешиваем лёгкий ситуативный контекст страницы function go(q, context, m) { if (chipsEl) chipsEl.style.display = 'none'; inp.value = ''; if (context == null) context = pageHint() || undefined; send(q, context, chatEl, m || mode); } inp.addEventListener('keydown', function (e) { if (e.key === 'Enter') go(inp.value); }); + var sendBtn = bubble.querySelector('.asst-send'); if (sendBtn) sendBtn.addEventListener('click', function () { go(inp.value); }); bubble.querySelectorAll('.asst-mode').forEach(function (b) { b.addEventListener('click', function () { mode = b.getAttribute('data-m');