From 2777b69eb347ea1df08e6fe064661205a175c261 Mon Sep 17 00:00:00 2001 From: DCCONSTRUCTIONS Date: Sun, 28 Jun 2026 18:04:59 +0300 Subject: [PATCH] Apply white glass UI canon --- seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md | 8 +- seo_mode/seo_mode/app/src/styles.css | 346 +++++++++++++++++- .../seo_mode/server/src/preview/routes.ts | 4 +- 3 files changed, 341 insertions(+), 17 deletions(-) diff --git a/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md b/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md index 5b91369..d568bd8 100644 --- a/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md +++ b/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md @@ -5,14 +5,14 @@ ## Визуальный тон - База: светлая Apple-like система, много воздуха, мягкие панели, скругления и спокойный серый фон. -- Главный акцент: тёмный градиент `#1f1f21 -> #3a332e`, как у активного этапа и основных submit/action-кнопок. -- Вторичный акцент: оранжевый `--accent: #f27a1a`, только для выбора папки, drag-and-drop и редких импортных действий. -- Избегаем случайной зелени/голубого/фиолета, если это не специально введённый статус. +- Главный акцент: тёмный neutral active `#202124 -> #111113`, как у активного этапа и основных submit/action-кнопок. +- Вторичный слой: white glass surfaces/controls через `--nodedc-glass-*`, без отдельных цветных акцентов. +- Избегаем случайной зелени/оранжевого/голубого/фиолета, если это не специально введённый статус. ## Кнопки - Primary actions: `Создать проект`, `Анализировать`, будущие основные шаги этапов. Используют тёмный градиент активного этапа. -- Import action: `Выбрать папку`. Остаётся оранжевой, потому что это отдельное действие загрузки/импорта. +- Import action: `Выбрать папку`. Использует тот же тёмный neutral active, без отдельного оранжевого акцента. - Icon actions: копировать, удалить, настройки. Круглые `42x42`, нейтральная светлая поверхность, тонкая граница, мягкая тень. - Danger icon: нейтральная круглая поверхность в покое, красный значок; красная заливка только на hover. diff --git a/seo_mode/seo_mode/app/src/styles.css b/seo_mode/seo_mode/app/src/styles.css index d975c30..814076f 100644 --- a/seo_mode/seo_mode/app/src/styles.css +++ b/seo_mode/seo_mode/app/src/styles.css @@ -15,6 +15,26 @@ --accent-soft: rgba(0, 0, 0, 0.08); --warning-bg: #e8e8e8; --danger-bg: #d8d8d8; + --nodedc-glass-panel-bg: rgba(255, 255, 255, 0.76); + --nodedc-glass-panel-bg-strong: rgba(255, 255, 255, 0.9); + --nodedc-glass-panel-bg-soft: rgba(255, 255, 255, 0.6); + --nodedc-glass-panel-surface: linear-gradient(180deg, rgba(255, 255, 255, 0.76) 0%, rgba(255, 255, 255, 0.44) 100%), var(--nodedc-glass-panel-bg); + --nodedc-glass-panel-surface-strong: linear-gradient(180deg, rgba(255, 255, 255, 0.86) 0%, rgba(255, 255, 255, 0.52) 100%), var(--nodedc-glass-panel-bg-strong); + --nodedc-glass-section-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.58) 0%, rgba(255, 255, 255, 0.28) 100%), rgba(244, 244, 246, 0.62); + --nodedc-glass-control-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.68) 0%, rgba(255, 255, 255, 0.36) 100%), rgba(244, 244, 246, 0.74); + --nodedc-glass-control-hover: linear-gradient(180deg, rgba(255, 255, 255, 0.78) 0%, rgba(255, 255, 255, 0.44) 100%), rgba(232, 232, 235, 0.82); + --nodedc-glass-control-active: linear-gradient(180deg, rgba(32, 32, 34, 0.98), rgba(20, 20, 22, 0.96)); + --nodedc-glass-outline: rgba(24, 32, 29, 0.1); + --nodedc-glass-outline-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.86), rgba(24, 32, 29, 0.08)); + --nodedc-glass-panel-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.75), 0 22px 72px rgba(24, 32, 29, 0.16); + --nodedc-glass-control-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7); + --nodedc-glass-blur: blur(44px) saturate(1.12); + --nodedc-glass-panel-blur: blur(64px) saturate(1.24) brightness(1.02); + --nodedc-header-dropdown-bg: var(--nodedc-glass-panel-surface-strong); + --nodedc-header-dropdown-item-bg: var(--nodedc-glass-control-bg); + --nodedc-header-dropdown-item-hover-bg: var(--nodedc-glass-control-hover); + --nodedc-header-dropdown-item-active-bg: rgba(24, 32, 29, 0.09); + --nodedc-header-dropdown-item-active-color: var(--ink); font-family: "Aptos", "Segoe UI", sans-serif; font-synthesis: none; text-rendering: optimizeLegibility; @@ -5589,13 +5609,13 @@ input[type="checkbox"] { } } -/* Stage navigation pass: dark hero, orange accent, and one logical screen per step. */ +/* Stage navigation pass: neutral accent and one logical screen per step. */ :root { - --accent: #f27a1a; - --accent-hover: #df650c; - --accent-soft: rgba(242, 122, 26, 0.13); - --accent-ring: rgba(242, 122, 26, 0.24); - --accent-shadow: rgba(242, 122, 26, 0.24); + --accent: #202124; + --accent-hover: #111113; + --accent-soft: rgba(24, 32, 29, 0.08); + --accent-ring: rgba(24, 32, 29, 0.14); + --accent-shadow: rgba(24, 32, 29, 0.18); } .nav-item { @@ -5609,7 +5629,7 @@ input[type="checkbox"] { .nav-item.active { color: #fff !important; - background: linear-gradient(135deg, #1f1f21, #3a332e) !important; + background: linear-gradient(135deg, #1f1f21, #29292c) !important; } .nav-item.active span, @@ -5620,21 +5640,21 @@ input[type="checkbox"] { .brand-mark { background: linear-gradient(145deg, rgba(255, 255, 255, 0.24), transparent 42%), - linear-gradient(145deg, #1d1d1f, #3b332d) !important; + linear-gradient(145deg, #1d1d1f, #2b2b2e) !important; } .topbar { color: #fff !important; background: - radial-gradient(circle at 90% 10%, rgba(242, 122, 26, 0.28), transparent 28%), + radial-gradient(circle at 90% 10%, rgba(255, 255, 255, 0.08), transparent 28%), radial-gradient(circle at 12% 96%, rgba(255, 255, 255, 0.08), transparent 28%), - linear-gradient(135deg, #111113 0%, #1e1d20 52%, #342316 100%) !important; + linear-gradient(135deg, #111113 0%, #1d1d20 52%, #242426 100%) !important; border-color: rgba(255, 255, 255, 0.08) !important; box-shadow: 0 22px 52px rgba(18, 16, 14, 0.18) !important; } .topbar::after { - background: radial-gradient(circle, rgba(242, 122, 26, 0.22), transparent 65%) !important; + background: radial-gradient(circle, rgba(255, 255, 255, 0.12), transparent 65%) !important; } .topbar h2 { @@ -7517,3 +7537,307 @@ input[type="checkbox"] { .project-scope-flow-canvas .scope-flow-toolbar .scope-flow-toolbar-button { transform: translateY(var(--tb-shift-y, 0px)) scale(var(--tb-scale, 1)) !important; } + +/* Canonical white glass pass: shared Engine/BIM-style surfaces and controls. */ +.workspace-page-menu, +.workspace-drawer, +.semantic-panel, +.semantic-page-plan-panel, +.semantic-brief-panel, +.semantic-landing-panel, +.semantic-verdict-panel, +.semantic-warning-list, +.semantic-gap-panel, +.semantic-seeds, +.semantic-ai-contract, +.semantic-style-panel, +.semantic-action-list, +.semantic-cluster-detail, +.market-panel, +.market-heading, +.market-state-card, +.market-wordstat-card, +.market-provider, +.market-columns section, +.market-next-actions { + background: var(--nodedc-glass-panel-surface-strong) !important; + border: 0 !important; + border-radius: 22px !important; + box-shadow: var(--nodedc-glass-panel-shadow) !important; + backdrop-filter: var(--nodedc-glass-panel-blur) !important; + -webkit-backdrop-filter: var(--nodedc-glass-panel-blur) !important; +} + +.workspace-drawer-header, +.workspace-page-menu-head { + border-color: rgba(24, 32, 29, 0.08) !important; +} + +.workspace-page-menu-list button, +.workspace-scope-list button, +.workspace-fields-drawer .section-editor-card, +.stage-3 .workspace-issue-list button, +.stage-3 .section-map-card, +.stage-3 .workspace-target-issues, +.semantic-metric-row, +.semantic-gap-row, +.semantic-scope-grid, +.semantic-scope-grid > div, +.semantic-quality, +.semantic-verdict-columns section, +.semantic-verdict-risk-list article, +.semantic-verdict-clusters > div, +.semantic-verdict-next, +.semantic-warning-row, +.semantic-page-plan-row, +.semantic-brief-row, +.semantic-brief-body section, +.semantic-brief-section, +.semantic-brief-quality-card, +.semantic-landing-row, +.market-wordstat-card > div:last-of-type, +.market-seed-list div, +.market-brief-list div, +.market-wordstat-results > div, +.semantic-cluster, +.semantic-detail-grid section, +.semantic-evidence-panel, +.semantic-source-list div { + background: var(--nodedc-glass-control-bg) !important; + border: 0 !important; + border-radius: 16px !important; + box-shadow: var(--nodedc-glass-control-shadow) !important; + backdrop-filter: var(--nodedc-glass-blur) !important; + -webkit-backdrop-filter: var(--nodedc-glass-blur) !important; +} + +.workspace-page-menu-list button:hover, +.workspace-scope-list button:hover, +.stage-3 .workspace-issue-list button:hover, +.stage-3 .section-map-card:hover, +.semantic-cluster:hover, +.semantic-cluster.active { + background: var(--nodedc-glass-control-hover) !important; + border: 0 !important; + box-shadow: var(--nodedc-glass-control-shadow), 0 0 0 1px rgba(24, 32, 29, 0.08) inset !important; + transform: none !important; +} + +.workspace-page-menu-list button.active, +.workspace-scope-list button.active, +.stage-3 .section-map-card.active, +.stage-3 .section-map-card.active:hover, +.workspace-fields-drawer .workspace-field-card.active { + color: var(--ink) !important; + background: var(--nodedc-header-dropdown-item-active-bg) !important; + border: 0 !important; + box-shadow: var(--nodedc-glass-control-shadow), 0 0 0 1px rgba(24, 32, 29, 0.12) inset !important; +} + +.workspace-page-menu-list button.active strong, +.workspace-page-menu-list button.active small, +.workspace-page-menu-list button.active em, +.workspace-scope-list button.active strong, +.workspace-scope-list button.active small, +.workspace-scope-list button.active em, +.stage-3 .section-map-card.active small, +.stage-3 .section-map-card.active p, +.stage-3 .section-map-card.active strong, +.stage-3 .section-map-card.active em { + color: var(--ink) !important; +} + +.workspace-page-menu-list button span, +.workspace-scope-list button span, +.stage-3 .section-map-card span, +.stage-3 .workspace-issue-list span, +.workspace-field-meta span, +.workspace-field-meta em, +.semantic-metric-row span, +.semantic-gap-row span, +.semantic-cluster div span, +.semantic-cluster div em, +.semantic-warning-row span, +.semantic-seeds span, +.semantic-scope-grid > span, +.semantic-quality > span, +.semantic-verdict-heading span, +.semantic-verdict-risk-list span, +.semantic-verdict-clusters span, +.semantic-token-list span, +.semantic-source-list span, +.semantic-page-plan-row > div:first-child span, +.semantic-brief-row summary > span, +.semantic-brief-row summary > .semantic-brief-quality, +.semantic-brief-section span, +.semantic-brief-quality-card > div:first-child span, +.semantic-brief-checks span, +.semantic-landing-row > span, +.market-wordstat-card > div:last-of-type span, +.market-state-card > div > span, +.market-provider > span, +.market-seed-list span, +.market-brief-list span, +.market-wordstat-results p span, +.semantic-term-cloud span { + color: var(--muted) !important; + background: rgba(24, 32, 29, 0.06) !important; + border: 0 !important; + box-shadow: var(--nodedc-glass-control-shadow) !important; +} + +.workspace-page-menu-list button.active span, +.workspace-scope-list button.active span, +.stage-3 .section-map-card.active span { + color: #fff !important; + background: var(--ink) !important; +} + +.workspace-page-menu-list button em, +.workspace-scope-list em, +.stage-3 .section-map-card em, +.workspace-field-meta span, +.workspace-field-meta em { + border-radius: 999px !important; +} + +.section-editor-card label span { + color: var(--muted) !important; + font-weight: 760 !important; +} + +.workspace-drawer-close, +.workspace-current-page-actions > button, +.workspace-current-page-actions .workspace-preview-mode-switch, +.scan-selection-bar button, +.scan-summary, +.scan-metric, +.audit-toolbar button, +.workspace-page-tabs button { + background: var(--nodedc-glass-control-bg) !important; + border: 0 !important; + box-shadow: var(--nodedc-glass-control-shadow) !important; + backdrop-filter: var(--nodedc-glass-blur) !important; + -webkit-backdrop-filter: var(--nodedc-glass-blur) !important; +} + +.workspace-drawer-close:hover, +.workspace-current-page-actions > button:hover, +.scan-selection-bar button:hover, +.audit-toolbar button:hover, +.workspace-page-tabs button:hover { + background: var(--nodedc-glass-control-hover) !important; + color: var(--ink) !important; +} + +.workspace-current-page-actions > button.active, +.workspace-page-control.open .workspace-page-control-trigger, +.audit-toolbar button.active, +.workspace-page-tabs button.active { + color: #fff !important; + background: var(--nodedc-glass-control-active) !important; +} + +.workspace-current-page-actions > button.active svg, +.workspace-page-control.open .workspace-page-control-trigger svg, +.audit-toolbar button.active svg, +.workspace-page-tabs button.active svg { + color: #fff !important; +} + +.workspace-fields-drawer .section-editor-card textarea, +.workspace-fields-drawer .section-editor-card pre, +.section-editor-card textarea, +.field input, +.project-edit-form input, +input:not([type="checkbox"]):not([type="radio"]):not([type="file"]), +textarea { + background: var(--nodedc-glass-control-bg) !important; + border-color: transparent !important; + box-shadow: var(--nodedc-glass-control-shadow) !important; +} + +.field input:focus, +.project-edit-form input:focus, +.section-editor-card textarea:focus, +input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):focus, +textarea:focus { + border-color: transparent !important; + box-shadow: var(--nodedc-glass-control-shadow), 0 0 0 3px rgba(24, 32, 29, 0.1) !important; +} + +.folder-picker-panel.active { + background: var(--nodedc-header-dropdown-item-active-bg) !important; + border-color: transparent !important; +} + +.folder-picker-panel .folder-pick-action, +.folder-picker-panel button.folder-pick-action, +.folder-pick-action { + color: #fff !important; + background: var(--nodedc-glass-control-active) !important; + border-color: transparent !important; + box-shadow: 0 12px 28px rgba(31, 31, 33, 0.18) !important; +} + +.folder-picker-panel .folder-pick-action:hover, +.folder-picker-panel button.folder-pick-action:hover, +.folder-pick-action:hover { + background: linear-gradient(135deg, #29292c, #343437) !important; + box-shadow: 0 16px 34px rgba(31, 31, 33, 0.22) !important; +} + +.semantic-metric-row span.ok, +.semantic-clean, +.semantic-metric-row span.danger, +.semantic-quality.ok > span, +.semantic-quality.warning > span, +.semantic-quality.problem > span, +.semantic-verdict-panel.low .semantic-verdict-heading span, +.semantic-verdict-panel.high .semantic-verdict-heading span, +.semantic-verdict-risk-list article.problem span, +.semantic-cluster.missing div span, +.semantic-page-plan-row.create > div:first-child span, +.semantic-page-plan-row.strengthen > div:first-child span, +.semantic-brief-row summary > .semantic-brief-quality.needs_work, +.semantic-brief-row summary > .semantic-brief-quality.blocked, +.semantic-brief-row summary > .semantic-brief-quality.legacy, +.semantic-brief-row.create summary > span, +.semantic-brief-row.create summary > .semantic-brief-quality.ready, +.semantic-brief-row.create summary > .semantic-brief-quality.needs_work, +.semantic-brief-row.create summary > .semantic-brief-quality.blocked, +.semantic-brief-row.create summary > .semantic-brief-quality.legacy, +.semantic-brief-checks .done, +.semantic-brief-checks .pass, +.semantic-brief-checks .pending, +.semantic-brief-checks .warn, +.semantic-brief-checks .fail, +.semantic-token-list.muted span.warning, +.semantic-token-list.muted span.problem, +.semantic-landing-row.create_target_page > span, +.market-state-card.not_collected > div > span, +.market-state-card.partial_ready > div > span, +.market-provider.connected > span, +.market-seed-list span.collected, +.market-seed-list span.collected_related_only, +.market-brief-list span.collected, +.market-seed-list span.ready_for_collection, +.market-brief-list span.ready_for_collection, +.market-seed-list span.collected_no_signal, +.market-state-card.not_configured > div > span, +.market-provider.not_configured > span, +.market-provider.not_implemented > span, +.market-seed-list span.collection_failed, +.market-brief-list span.collection_failed, +.market-seed-list span.not_configured, +.market-brief-list span.not_configured { + color: var(--muted) !important; + background: rgba(24, 32, 29, 0.06) !important; +} + +.workspace-target-issues, +.stage-3 .workspace-target-issues { + color: var(--muted) !important; + background: var(--nodedc-glass-control-bg) !important; + border: 0 !important; +} diff --git a/seo_mode/seo_mode/server/src/preview/routes.ts b/seo_mode/seo_mode/server/src/preview/routes.ts index 0ffb5d0..cd1842b 100644 --- a/seo_mode/seo_mode/server/src/preview/routes.ts +++ b/seo_mode/seo_mode/server/src/preview/routes.ts @@ -523,10 +523,10 @@ function buildPreviewBridgeScript() { marker.style.placeItems = "center"; marker.style.padding = "0"; marker.style.color = "#fff"; - marker.style.background = "#f27a1a"; + marker.style.background = "#202124"; marker.style.border = "2px solid rgba(255,255,255,.95)"; marker.style.borderRadius = "999px"; - marker.style.boxShadow = "0 6px 16px rgba(242,122,26,.28)"; + marker.style.boxShadow = "0 6px 16px rgba(24,32,29,.24)"; marker.style.cursor = "pointer"; marker.style.font = "700 12px/1 Inter, Arial, sans-serif"; marker.style.pointerEvents = "auto";