diff --git a/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md b/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md index d568bd8..a2d5779 100644 --- a/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md +++ b/seo_mode/seo_mode/SEO-farm/DESIGN_SYSTEM.md @@ -6,8 +6,9 @@ - База: светлая Apple-like система, много воздуха, мягкие панели, скругления и спокойный серый фон. - Главный акцент: тёмный neutral active `#202124 -> #111113`, как у активного этапа и основных submit/action-кнопок. -- Вторичный слой: white glass surfaces/controls через `--nodedc-glass-*`, без отдельных цветных акцентов. +- Вторичный слой: white glass surfaces/controls через `--nodedc-glass-*`, без отдельных цветных акцентов. Glass-панели должны оставаться прозрачными: материал строится на низкой alpha-подложке, `backdrop-filter` и outline-gradient, а не на глухой белой заливке. - Избегаем случайной зелени/оранжевого/голубого/фиолета, если это не специально введённый статус. +- Точки ошибок в preview-сайте: розовый marker `#ff4fb8`, активный `#d81b7d`. ## Кнопки diff --git a/seo_mode/seo_mode/app/src/App.tsx b/seo_mode/seo_mode/app/src/App.tsx index 649f6d8..9f0cf48 100644 --- a/seo_mode/seo_mode/app/src/App.tsx +++ b/seo_mode/seo_mode/app/src/App.tsx @@ -1059,7 +1059,7 @@ type WorkspaceTarget = { }; type WorkspacePreviewMode = "desktop" | "mobile"; -type WorkspaceDrawerPanel = "fields" | "issues" | "scope"; +type WorkspaceDrawerPanel = "fields" | "issues"; const WORKSPACE_PREVIEW_MODES: Array<{ id: WorkspacePreviewMode; label: string }> = [ { id: "desktop", label: "Desktop" }, @@ -3522,7 +3522,11 @@ export function App() { null; const activeWorkspaceMarkers = activeWorkspaceKey ? (workspacePreviewMarkers[activeWorkspaceKey] ?? []) : []; const activeWorkspacePreviewMode = activeWorkspaceKey ? (workspacePreviewModes[activeWorkspaceKey] ?? "desktop") : "desktop"; - const activeWorkspaceDrawers = activeWorkspaceKey ? (workspaceDrawers[activeWorkspaceKey] ?? []) : []; + const activeWorkspaceDrawers = activeWorkspaceKey + ? (workspaceDrawers[activeWorkspaceKey] ?? []).filter( + (drawer): drawer is WorkspaceDrawerPanel => drawer === "fields" || drawer === "issues" + ) + : []; const isWorkspacePageMenuOpen = activeWorkspaceKey ? Boolean(workspacePageMenus[activeWorkspaceKey]) : false; const previewWorkspaceScopeId = workspacePreviewScopeIds[project.id] ?? activeWorkspaceScopeItem?.scopeId ?? null; const previewWorkspaceScopeItem = @@ -4775,7 +4779,7 @@ export function App() {
- Активная зона {activeWorkspacePageIndex + 1}/{selectedWorkspaceScopeItems.length} · выбранный scope + Активная страница {activeWorkspacePageIndex + 1}/{selectedWorkspaceScopeItems.length} {activeWorkspaceScopeItem.title} {activeWorkspaceScopeItem.pathLabel} @@ -4785,7 +4789,7 @@ export function App() {
Замечаний на активной странице: {activeWorkspaceIssues.length} - В выбранном scope: {selectedCoverageIssueCount} + В выбранных страницах: {selectedCoverageIssueCount} Warning: {activeWorkspaceIssueCounts.warnings} · Info: {activeWorkspaceIssueCounts.info}
@@ -4807,7 +4811,7 @@ export function App() { {isWorkspacePageMenuOpen ? (
- Страницы и секции scope + Страницы и секции Переключает preview, ошибки и поля рабочей зоны.
{selectedWorkspaceScopeItems.length > 0 ? ( @@ -4826,7 +4830,8 @@ export function App() { onClick={() => { setWorkspacePageMenus((currentMenus) => ({ ...currentMenus, - [activeWorkspaceKey]: false + [activeWorkspaceKey]: false, + [pageWorkspaceKey]: true })); void handleOpenPageWorkspace(project, scopeItem, { silent: true }); }} @@ -4843,21 +4848,12 @@ export function App() {
) : ( - В выбранном scope пока нет рабочих страниц или секций. + В выбранном наборе пока нет рабочих страниц или секций. )}
) : null}
-
- {activeWorkspaceDrawer === "scope" ? ( -
- {selectedWorkspaceScopeItems.map((scopeItem, pageIndex) => { - const pageWorkspaceKey = getWorkspaceKey(project.id, scopeItem.scopeId); - const isOpening = busyWorkspaceKey === pageWorkspaceKey; - const isActivePage = activeWorkspaceScopeItem?.scopeId === scopeItem.scopeId; - const pageIssues = getPageIssues(scanSummary, scopeItem.pageId); - - return ( - - ); - })} -
- ) : activeWorkspaceDrawer === "fields" ? ( + {activeWorkspaceDrawer === "fields" ? (
{activeWorkspaceTargets.length > 0 ? ( activeWorkspaceTargets.map((target) => { diff --git a/seo_mode/seo_mode/app/src/styles.css b/seo_mode/seo_mode/app/src/styles.css index 814076f..b0d613b 100644 --- a/seo_mode/seo_mode/app/src/styles.css +++ b/seo_mode/seo_mode/app/src/styles.css @@ -15,25 +15,25 @@ --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-panel-bg: rgba(255, 255, 255, 0.18); + --nodedc-glass-panel-bg-strong: rgba(255, 255, 255, 0.26); + --nodedc-glass-panel-bg-soft: rgba(255, 255, 255, 0.12); + --nodedc-glass-panel-surface: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.1) 100%), var(--nodedc-glass-panel-bg); + --nodedc-glass-panel-surface-strong: linear-gradient(180deg, rgba(255, 255, 255, 0.38) 0%, rgba(255, 255, 255, 0.14) 100%), var(--nodedc-glass-panel-bg-strong); + --nodedc-glass-section-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0.08) 100%), rgba(255, 255, 255, 0.12); + --nodedc-glass-control-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0.08) 100%), rgba(255, 255, 255, 0.12); + --nodedc-glass-control-hover: linear-gradient(180deg, rgba(255, 255, 255, 0.34) 0%, rgba(255, 255, 255, 0.12) 100%), rgba(255, 255, 255, 0.2); --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-glass-outline-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.34) 28%, rgba(24, 32, 29, 0.1) 100%); + --nodedc-glass-panel-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.42), 0 18px 60px rgba(24, 32, 29, 0.14); + --nodedc-glass-control-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.34); + --nodedc-glass-blur: blur(24px) saturate(128%) brightness(1.05); + --nodedc-glass-panel-blur: blur(64px) saturate(150%) brightness(1.08); --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-bg: rgba(255, 255, 255, 0.24); --nodedc-header-dropdown-item-active-color: var(--ink); font-family: "Aptos", "Segoe UI", sans-serif; font-synthesis: none; @@ -1362,10 +1362,10 @@ input { place-items: center; padding: 0; color: #fff; - background: var(--accent); + background: #ff4fb8; border: 2px solid rgba(255, 255, 255, 0.92); border-radius: 999px; - box-shadow: 0 8px 18px rgba(242, 122, 26, 0.24); + box-shadow: 0 8px 18px rgba(255, 79, 184, 0.3); cursor: pointer; font-size: 12px; font-weight: 750; @@ -1374,8 +1374,8 @@ input { } .workspace-preview-markers button.active { - background: var(--ink); - box-shadow: 0 0 0 4px rgba(242, 122, 26, 0.18); + background: #d81b7d; + box-shadow: 0 0 0 4px rgba(255, 79, 184, 0.18); } .workspace-subheading { @@ -7440,12 +7440,14 @@ input[type="checkbox"] { } .stage-3 .workspace-preview-markers button { - background: var(--accent) !important; + background: #ff4fb8 !important; + box-shadow: 0 8px 18px rgba(255, 79, 184, 0.3) !important; transform: none !important; } .stage-3 .workspace-preview-markers button.active { - background: var(--ink) !important; + background: #d81b7d !important; + box-shadow: 0 0 0 4px rgba(255, 79, 184, 0.18) !important; } .stage-6 .project-setup, @@ -7566,6 +7568,89 @@ input[type="checkbox"] { 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; + isolation: isolate; +} + +.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 { + overflow: hidden !important; +} + +.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 { + position: relative; +} + +.workspace-page-menu::after, +.workspace-drawer::after, +.semantic-panel::after, +.semantic-page-plan-panel::after, +.semantic-brief-panel::after, +.semantic-landing-panel::after, +.semantic-verdict-panel::after, +.semantic-warning-list::after, +.semantic-gap-panel::after, +.semantic-seeds::after, +.semantic-ai-contract::after, +.semantic-style-panel::after, +.semantic-action-list::after, +.semantic-cluster-detail::after, +.market-panel::after, +.market-heading::after, +.market-state-card::after, +.market-wordstat-card::after, +.market-provider::after, +.market-columns section::after, +.market-next-actions::after { + content: ""; + position: absolute; + inset: 0; + z-index: 2; + padding: 1px; + pointer-events: none; + border-radius: inherit; + background: var(--nodedc-glass-outline-gradient); + -webkit-mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; } .workspace-drawer-header, diff --git a/seo_mode/seo_mode/server/src/preview/routes.ts b/seo_mode/seo_mode/server/src/preview/routes.ts index cd1842b..ae572c7 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 = "#202124"; + marker.style.background = "#ff4fb8"; marker.style.border = "2px solid rgba(255,255,255,.95)"; marker.style.borderRadius = "999px"; - marker.style.boxShadow = "0 6px 16px rgba(24,32,29,.24)"; + marker.style.boxShadow = "0 6px 16px rgba(255,79,184,.32)"; marker.style.cursor = "pointer"; marker.style.font = "700 12px/1 Inter, Arial, sans-serif"; marker.style.pointerEvents = "auto";