sync: UI animations, select styling, TLS verify flag via proxy second line, brand spacing

This commit is contained in:
2025-09-27 18:46:52 +03:00
parent 135c393eda
commit 2abfbb4b1a
52 changed files with 8029 additions and 1408 deletions

View File

@@ -15,31 +15,38 @@ html, body, button, input, select, textarea, code, pre, a, .chip-btn, .group-tit
--node: #0e1116;
--node-border: #334155;
--node-selected: #1f2937;
/* Базовый цвет проводов по умолчанию */
--connector: #7aa2f7;
--connector-muted: #3b82f6;
/* Неброские цвета для разных типов/веток */
--wire-true: #34d399; /* мягкий зелёный для If:true */
--wire-false: #94a3b8; /* сланцево‑серый для If:false */
--wire-provider: #5b86e5; /* приглушённый синий */
--wire-raw: #8b7de6; /* мягкий фиолетовый */
--wire-setvars: #4fbfa0; /* приглушённая мята */
--wire-return: #93a9d1; /* холодный серо‑синий */
/* DRY tokens: unified shadows and transitions */
--ring3-22-shadow: 0 0 0 3px rgba(96,165,250,.22), 0 4px 10px rgba(0,0,0,.35);
--ring3-20-shadow: 0 0 0 3px rgba(96,165,250,.20), 0 4px 10px rgba(0,0,0,.35);
--ring2-20-shadow: 0 0 0 2px rgba(96,165,250,.20), 0 2px 6px rgba(0,0,0,.35);
--focus-ring3-20: 0 0 0 3px rgba(96,165,250,.20);
--focus-ring3-22: 0 0 0 3px rgba(96,165,250,.22);
--tr-base: border-color .12s ease, box-shadow .12s ease, background-color .12s ease, color .12s ease;
--tr-pop: transform .12s ease;
--tr-pop-fast: transform .08s ease;
}
html, body {
height: 100%;
overflow: hidden; /* убираем общие скролл-бары страницы, чтобы не перекрывать правую стрелку */
}
/* Глобальные контейнеры и скроллы */
html, body {
height: 100%;
overflow: hidden; /* убираем общие скролл-бары страницы */
}
#container {
position: relative; /* якорь для абсолютных стрелок-переключателей */
}
/* Глобальные контейнеры и скроллы */
html, body {
height: 100%;
overflow: hidden; /* убираем общие скролл-бары страницы */
}
#container {
position: relative; /* якорь для абсолютных стрелок-переключателей */
}
/* Grid areas to hard-pin layout regardless of hidden panels or absolute children */
#container {
display: grid;
@@ -77,7 +84,36 @@ html, body {
border: 1px solid var(--node-border);
color: #e5e7eb;
border-radius: 12px 12px 0 0;
padding: 6px 10px;
padding: 4px 8px; /* компактнее заголовок */
font-size: 12px; /* компактнее шрифт заголовка */
line-height: 1.2;
}
/* Иконка типа ноды в заголовке (монохромная, спокойная) */
.drawflow .drawflow-node .title-box .node-ico {
display: inline-block;
width: 14px;
height: 14px;
margin-right: 6px;
vertical-align: -2px;
background-size: 14px 14px;
background-repeat: no-repeat;
filter: opacity(.9);
}
/* SVG-иконки по типам (цвета под стиль проекта) */
.drawflow .drawflow-node .title-box .node-ico-If {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 4v6a4 4 0 0 0 4 4h4'/><polyline points='14 14 18 10 14 6'/></svg>");
}
.drawflow .drawflow-node .title-box .node-ico-ProviderCall {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235b86e5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 15a4 4 0 0 0 4 4h10a4 4 0 0 0 4-4'/><path d='M7 19V5a4 4 0 0 1 4-4h2a4 4 0 0 1 4 4v14'/></svg>");
}
.drawflow .drawflow-node .title-box .node-ico-RawForward {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238b7de6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='5 12 19 12'/><polyline points='12 5 19 12 12 19'/></svg>");
}
.drawflow .drawflow-node .title-box .node-ico-SetVars {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%234fbfa0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='3'/><path d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06A1.65 1.65 0 0 0 15 19.4a1.65 1.65 0 0 0-1 .6l-.09.1a2 2 0 1 1-3.2 0l-.09-.1a1.65 1.65 0 0 0-1-.6 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-.6-1l-.1-.09a2 2 0 1 1 0-3.2l.1-.09a1.65 1.65 0 0 0 .6-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06A2 2 0 1 1 6.94 2.6l.06.06A1.65 1.65 0 0 0 8 3.6a1.65 1.65 0 0 0 1-.6l.09-.1a2 2 0 1 1 3.2 0l.09.1a1.65 1.65 0 0 0 1 .6 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 .6 1l.1.09a2 2 0 1 1 0 3.2l-.1.09a1.65 1.65 0 0 0-.6 1z'/></svg>");
}
.drawflow .drawflow-node .title-box .node-ico-Return {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2393a9d1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 10l-5 5 5 5'/><path d='M20 4v7a4 4 0 0 1-4 4H4'/></svg>");
}
.drawflow .drawflow-node .box {
@@ -87,11 +123,28 @@ html, body {
color: #e5e7eb;
border-radius: 0 0 12px 12px;
overflow: hidden; /* не даём контенту вылезать за края */
font-size: 11px; /* компактнее содержимое */
line-height: 1.25;
}
/* Контент превью внутри .box: можем скрывать его в LOD, не ломая геометрию ноды */
/* Контент превью внутри .box: можем скрывать его в LOD, не меняя коробку ноды */
.drawflow .drawflow-node .node-preview {
pointer-events: none;
pointer-events: auto; /* разрешаем клики по summary (<details>) */
opacity: .85;
font-size: 10.5px; /* мелкий общий текст превью */
}
/* На самом канвасе поля превью недоступны для редактирования/клика */
.drawflow .drawflow-node .node-preview input,
.drawflow .drawflow-node .node-preview textarea {
pointer-events: none;
}
.drawflow .drawflow-node .node-preview label {
font-size: 10px;
margin: 4px 0 2px;
}
/* Адресные поля читаемые «обычным» кеглем */
.drawflow .drawflow-node .node-preview .np-url,
.drawflow .drawflow-node .node-preview .np-endpoint {
font-size: 12px !important;
}
.drawflow .drawflow-node .box textarea,
@@ -104,6 +157,9 @@ html, body {
width: 100%;
max-width: 100%;
box-sizing: border-box;
padding: 6px 8px; /* компактнее поля превью */
font-size: 10.5px; /* мелкий текст по умолчанию */
resize: none; /* запрет изменения размера на канвасе */
}
.df-node .box textarea {
@@ -112,6 +168,7 @@ html, body {
overflow-y: auto; /* только вертикальный скролл при необходимости */
overflow-x: hidden; /* убираем горизонтальный скролл внутри textarea */
max-height: 180px; /* предотвращаем бесконечную высоту */
resize: none; /* запрет ручного ресайза превью */
}
/* Выделение выбранного узла — мягкое */
@@ -120,6 +177,15 @@ html, body {
border-color: var(--accent);
box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
}
/* Привести disabled к виду обычных превью (без «серости» браузера) */
.drawflow .drawflow-node .box input[disabled],
.drawflow .drawflow-node .box textarea[disabled] {
opacity: 1;
color: #e5e7eb;
background: #0f141a;
border-color: #2b3646;
cursor: default;
}
/* Порты: более аккуратные, без «оранжевого» */
.drawflow .drawflow-node .inputs .input,
@@ -131,19 +197,36 @@ html, body {
box-shadow: 0 0 0 2px rgba(0,0,0,.25);
}
/* Линии соединений: плавные, аккуратные цвета */
/* Линии соединений: тоньше и спокойнее */
.drawflow .connection .main-path {
stroke: var(--connector) !important;
/* Толщина линии масштабируется от зума (var(--zoom) задаётся на #canvas из JS) */
stroke-width: clamp(1.6px, calc(3px / var(--zoom, 1)), 6px) !important;
opacity: 0.95 !important;
stroke-width: clamp(1px, calc(2.2px / var(--zoom, 1)), 4.5px) !important;
opacity: 0.9 !important;
stroke-linecap: round; /* сглаженные окончания */
stroke-linejoin: round; /* сглажённые соединения */
}
/* Connection styling classes (set by JS; stable even if Drawflow re-renders paths) */
.drawflow .connection.conn-if-true .main-path {
stroke: var(--wire-true) !important;
stroke-dasharray: 6 6 !important;
}
.drawflow .connection.conn-if-false .main-path {
stroke: var(--wire-false) !important;
stroke-dasharray: 6 6 !important;
}
.drawflow .connection.conn-provider .main-path { stroke: var(--wire-provider) !important; }
.drawflow .connection.conn-raw .main-path { stroke: var(--wire-raw) !important; }
.drawflow .connection.conn-setvars .main-path { stroke: var(--wire-setvars) !important; }
.drawflow .connection.conn-return .main-path { stroke: var(--wire-return) !important; }
/* Подсветка входящих к ошибочной ноде рёбер (мягкий красный) */
.drawflow .connection.conn-upstream-err .main-path { stroke: #ef4444 !important; opacity: .95 !important; }
.drawflow .connection .main-path.selected,
.drawflow .connection:hover .main-path {
stroke: var(--accent-2) !important;
/* На hover/selected — немного толще базовой формулы */
stroke-width: clamp(2px, calc(3.6px / var(--zoom, 1)), 7px) !important;
/* На hover/selected — слегка толще базовой формулы */
stroke-width: clamp(1.3px, calc(2.6px / var(--zoom, 1)), 5px) !important;
}
/* Точки изгибов/ручки */
@@ -268,19 +351,19 @@ a.chip-btn {
color: #e5e7eb;
border: 1px solid #334155;
box-shadow: 0 2px 6px rgba(0,0,0,.35);
transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease, border-color .12s ease, color .12s ease;
transition: var(--tr-base), var(--tr-pop);
user-select: none;
}
.chip-btn:hover,
a.chip-btn:hover {
background: #1f2937;
border-color: var(--accent-2);
box-shadow: 0 0 0 3px rgba(96,165,250,.22), 0 4px 10px rgba(0,0,0,.35);
box-shadow: var(--ring3-22-shadow);
}
.chip-btn:active,
a.chip-btn:active {
transform: translateY(1px);
box-shadow: 0 0 0 2px rgba(96,165,250,.20), 0 2px 6px rgba(0,0,0,.35);
box-shadow: var(--ring2-20-shadow);
}
/* Инпуты и селекты в шапке — в одном визуальном ряду с чипами */
@@ -297,7 +380,7 @@ a.chip-btn:active {
}
.top-input:focus {
border-color: var(--accent-2);
box-shadow: 0 0 0 3px rgba(96,165,250,.20);
box-shadow: var(--focus-ring3-20);
}
/* Внутренние заголовки в блоке ноды */
@@ -322,7 +405,7 @@ a.chip-btn:active {
box-shadow: 0 2px 6px rgba(0,0,0,.35);
cursor: pointer;
opacity: .85;
transition: transform .12s ease, opacity .12s ease, box-shadow .12s ease, border-color .12s ease, background-color .12s ease;
transition: var(--tr-base), var(--tr-pop), opacity .12s ease;
}
.drawflow .connection:hover foreignObject,
.drawflow .connection:hover [class*="remove"],
@@ -331,7 +414,7 @@ a.chip-btn:active {
opacity: 1;
transform: scale(1.05);
border-color: var(--accent-2);
box-shadow: 0 0 0 3px rgba(96,165,250,.20), 0 4px 10px rgba(0,0,0,.35);
box-shadow: var(--ring3-20-shadow);
}
/* If delete control is rendered inside foreignObject, normalize inner box */
.drawflow .connection foreignObject div,
@@ -685,7 +768,7 @@ a.chip-btn:active {
/* Port hover affordance (no heavy effects) */
.drawflow .drawflow-node .inputs .input,
.drawflow .drawflow-node .outputs .output {
transition: transform .08s ease;
transition: var(--tr-pop-fast);
will-change: transform;
}
.drawflow .drawflow-node .inputs .input:hover,
@@ -712,18 +795,18 @@ a.chip-btn:active {
box-shadow: 0 2px 6px rgba(0,0,0,.35) !important;
cursor: pointer !important;
z-index: 10 !important;
transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease, border-color .12s ease, color .12s ease !important;
transition: var(--tr-base), var(--tr-pop) !important;
}
.drawflow .drawflow-node .close:hover {
transform: scale(1.06) !important;
background: #1f2937 !important;
border-color: var(--accent-2) !important;
color: #f8fafc !important;
box-shadow: 0 0 0 3px rgba(96,165,250,.22), 0 4px 10px rgba(0,0,0,.35) !important;
box-shadow: var(--ring3-22-shadow) !important;
}
.drawflow .drawflow-node .close:active {
transform: scale(0.98) !important;
box-shadow: 0 0 0 2px rgba(96,165,250,.20), 0 2px 6px rgba(0,0,0,.35) !important;
box-shadow: var(--ring2-20-shadow) !important;
}
/* Drawflow floating delete handle (class: .drawflow-delete) — restyle but keep behavior */
#drawflow .drawflow-delete,
@@ -741,7 +824,7 @@ a.chip-btn:active {
box-shadow: 0 2px 6px rgba(0,0,0,.35) !important;
cursor: pointer !important;
z-index: 1000 !important;
transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease, border-color .12s ease !important;
transition: var(--tr-base), var(--tr-pop) !important;
}
#drawflow .drawflow-delete::before,
.drawflow-delete::before {
@@ -757,7 +840,7 @@ a.chip-btn:active {
transform: translate(-50%, -50%) scale(1.06) !important;
background: #1f2937 !important;
border-color: var(--accent-2) !important;
box-shadow: 0 0 0 3px rgba(96,165,250,.22), 0 4px 10px rgba(0,0,0,.35) !important;
box-shadow: var(--ring3-22-shadow) !important;
}
#drawflow .drawflow-delete:active,
.drawflow-delete:active {
@@ -766,7 +849,7 @@ a.chip-btn:active {
/* Execution highlight states (SSE-driven) */
.drawflow .drawflow-node .title-box,
.drawflow .drawflow-node .box {
transition: border-color .12s ease, box-shadow .12s ease, background-color .12s ease;
transition: var(--tr-base);
}
.drawflow .drawflow-node.node-running .title-box,
@@ -808,16 +891,6 @@ a.chip-btn:active {
transform: translate(-50%, -100%);
z-index: 1000; /* above nodes/edges but below menus */
}
/* Снимаем скролл-бары с контейнера Drawflow, чтобы не перекрывать правую стрелку */
#drawflow {
overflow: hidden !important;
position: relative;
z-index: 1; /* гарантируем, что канвас виден под HUD и над фоном */
/* Растянем контейнер Drawflow на всю центральную колонку */
width: 100%;
height: 100%;
display: block;
}
/* Panels collapse controls and layout */
#container.collapse-left {
@@ -1002,11 +1075,7 @@ select#pm-role {
outline: none;
font: 12px/1 Inter, system-ui, Arial, sans-serif;
transition:
border-color .12s ease,
box-shadow .12s ease,
background-color .12s ease,
color .12s ease;
transition: var(--tr-base);
}
/* Hover and focus states consistent with .top-input */
@@ -1025,7 +1094,7 @@ select#vars-scope:focus,
select.v-mode:focus,
select#pm-role:focus {
border-color: var(--accent-2);
box-shadow: 0 0 0 3px rgba(96,165,250,.20);
box-shadow: var(--focus-ring3-20);
}
/* Compact width contexts: keep natural width unless container forces 100% */
@@ -1202,4 +1271,196 @@ header { position: relative; }
}
#inspector .var-row .v-del {
flex: 0 0 auto;
}
}
/* --- Wire labels and arrows overlay --- */
#wire-labels {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 4; /* над линиями, под панелями */
}
.wire-label {
position: absolute;
transform: translate(-50%, -50%);
background: #10151c;
color: #e5e7eb;
border: 1px solid rgba(148,163,184,.35);
border-radius: 6px;
padding: 1px 4px;
font: 10px/1.2 Inter, system-ui, Arial, sans-serif;
white-space: nowrap;
opacity: .9;
user-select: none;
}
.wire-arrow {
position: absolute;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 8px solid var(--connector); /* перекрашивается inline из цвета линии */
transform-origin: 50% 70%;
opacity: .95;
}
/* Димминг посторонних связей при фокусе ноды */
.drawflow .connection.dim .main-path {
opacity: .35 !important;
}
/* --- Сворачиваемые блоки превью в нодах --- */
.np-coll { margin: 4px 0; }
.np-coll > summary {
list-style: none;
cursor: pointer;
color: var(--muted);
font-size: 10px;
margin: 4px 0 2px;
}
.np-coll > summary::-webkit-details-marker { display: none; }
.np-coll[open] > summary { color: #cbd5e1; }
/* groups overlay removed */
/* --- Canvas preview sanitization: hide hints/labels/checkboxes (only on canvas node previews) --- */
/* Скрываем визуальные хинты, подписи и «галочки» только внутри превью нод на канвасе.
Summary секции (headers/template) остаются видимыми, textarea/inputs продолжают отображать значения. */
#canvas .drawflow .drawflow-node .node-preview .hint,
#canvas .drawflow .drawflow-node .node-preview label,
#canvas .drawflow .drawflow-node .node-preview input[type="checkbox"] {
display: none !important;
}
/* --- Unified checkbox style across UI --- */
/* Единый тёмный стиль чекбоксов под тему проекта (акцент — var(--accent-2)).
Применяется ко всей UI (инспектор, «Запуск», Prompt Blocks, STOREпанель и т.д.).
На канвасе в превью чекбоксы скрыты блоком выше. */
input[type="checkbox"] {
-webkit-appearance: none;
appearance: none;
width: 16px;
height: 16px;
display: inline-block;
vertical-align: -2px;
border: 1px solid #334155;
border-radius: 4px;
background: #0f141a;
box-shadow: 0 0 0 0 rgba(96,165,250,0.0);
transition:
background-color .12s ease,
border-color .12s ease,
box-shadow .12s ease,
transform .06s ease;
cursor: pointer;
}
input[type="checkbox"]:hover {
background: #121820;
border-color: var(--accent-2);
box-shadow: 0 0 0 3px rgba(96,165,250,.18);
}
input[type="checkbox"]:active {
transform: scale(0.96);
}
input[type="checkbox"]:checked {
border-color: var(--accent-2);
background-color: #0f141a;
background-image: url("data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2360a5fa' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'&gt;&lt;polyline points='20 6 9 17 4 12'/&gt;&lt;/svg&gt;");
background-repeat: no-repeat;
background-position: center;
background-size: 12px 12px;
}
input[type="checkbox"]:focus-visible {
outline: none;
border-color: var(--accent-2);
box-shadow: var(--focus-ring3-22);
}
input[type="checkbox"]:disabled {
opacity: .6;
cursor: not-allowed;
box-shadow: none;
}
/* --- Enhanced checkbox visual: add glowing blue dot at center --- */
/* Применяется ко всем чекбоксам в UI (инспектор, Запуск, Prompt Blocks, STORE и т.д.).
В превью нод на канвасе чекбоксы скрыты ранее добавленным правилом. */
input[type="checkbox"] {
position: relative; /* для центрирования псевдо-элемента */
overflow: visible; /* безопасно для свечения */
}
input[type="checkbox"]::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
width: 6px;
height: 6px;
border-radius: 999px;
background: var(--accent-2);
transform: translate(-50%, -50%) scale(0.6);
opacity: .6;
/* мягкое синее свечение в покое */
box-shadow:
0 0 4px rgba(96,165,250,.45),
0 0 10px rgba(96,165,250,.25);
transition:
transform .12s ease,
opacity .12s ease,
box-shadow .12s ease;
}
input[type="checkbox"]:checked::after {
transform: translate(-50%, -50%) scale(1.0);
opacity: 1;
/* усиленное свечение при включении */
box-shadow:
0 0 6px rgba(96,165,250,.80),
0 0 14px rgba(96,165,250,.60),
0 0 24px rgba(96,165,250,.35);
}
input[type="checkbox"]:disabled::after {
opacity: .35;
box-shadow: 0 0 2px rgba(96,165,250,.25);
}
/* --- Unified number input style across UI --- */
/* Единый стиль для всех input[type=number], включая инспектор, «Запуск», SERVICEпанели и т.д. */
input[type="number"] {
width: 100%;
background: #0f141a;
color: #e5e7eb;
border: 1px solid #2b3646;
border-radius: 8px;
padding: 6px 8px;
height: 32px;
box-sizing: border-box;
font: 12px/1 Inter, system-ui, Arial, sans-serif;
transition: var(--tr-base);
}
input[type="number"]:hover {
background: #121820;
border-color: var(--accent-2);
}
input[type="number"]:focus {
outline: none;
border-color: var(--accent-2);
box-shadow: var(--focus-ring3-20);
}
input[type="number"]:disabled {
opacity: .6;
cursor: not-allowed;
box-shadow: none;
}
/* Убираем нативные «стрелочки», чтобы стиль был единым во всех браузерах */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
/* --- Canvas preview sanitization (напоминание): хинты/лейблы/чекбоксы скрыты в превью --- */
/* Секции summary (headers/template) остаются видимыми */