From d3e2859ca1069f512b272f76f31353f38fca20f4 Mon Sep 17 00:00:00 2001 From: DCCONSTRUCTIONS Date: Sat, 11 Jul 2026 13:07:47 +0300 Subject: [PATCH] Unify modal and inspector glass material --- apps/catalog/src/CatalogApp.tsx | 12 ++++++++++-- docs/COMPONENTS.md | 2 +- packages/tokens/themes.css | 4 ++-- packages/tokens/tokens.css | 6 +++--- packages/ui-core/src/glass.ts | 10 ++++++---- packages/ui-core/styles.css | 10 ---------- packages/ui-react/src/Window.tsx | 3 ++- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/apps/catalog/src/CatalogApp.tsx b/apps/catalog/src/CatalogApp.tsx index 9fe8138..b26ac59 100644 --- a/apps/catalog/src/CatalogApp.tsx +++ b/apps/catalog/src/CatalogApp.tsx @@ -419,7 +419,15 @@ export function CatalogApp() { if (media.faviconFileName) setFaviconFileName(media.faviconFileName); if (media.faviconAssets) setFaviconAssets(media.faviconAssets); } - if (stored.glass) setGlassMaterial({ ...defaultGlassMaterial, ...stored.glass }); + if (stored.glass) { + const legacyDefaultOpacity = stored.glass.version !== 4 && stored.glass.tintOpacity === 54; + setGlassMaterial({ + ...defaultGlassMaterial, + ...stored.glass, + version: 4, + tintOpacity: legacyDefaultOpacity ? defaultGlassMaterial.tintOpacity : stored.glass.tintOpacity, + }); + } const toolbar = stored.toolbar; if (toolbar) { if (toolbar.placement === "left" || toolbar.placement === "right" || toolbar.placement === "bottom") setToolbarPlacement(toolbar.placement); @@ -904,7 +912,7 @@ export function CatalogApp() {
setGlassMaterial((current) => ({ ...current, tintHex }))} /> - `${value}%`} onChange={(tintOpacity) => setGlassMaterial((current) => ({ ...current, tintOpacity }))} /> + `${value}%`} onChange={(tintOpacity) => setGlassMaterial((current) => ({ ...current, version: 4, tintOpacity }))} /> `${value}px`} onChange={(blur) => setGlassMaterial((current) => ({ ...current, blur }))} /> `${value}%`} onChange={(saturation) => setGlassMaterial((current) => ({ ...current, saturation }))} /> `${value}%`} onChange={(brightness) => setGlassMaterial((current) => ({ ...current, brightness }))} /> diff --git a/docs/COMPONENTS.md b/docs/COMPONENTS.md index 493dc2d..4f00a89 100644 --- a/docs/COMPONENTS.md +++ b/docs/COMPONENTS.md @@ -12,7 +12,7 @@ Material rim допустим только как часть floating glass. Жёсткая цветная рамка, случайный browser outline или debug border не являются rim. -`GlassMaterialSurface` — отдельный переносимый контракт Engine Glass V4. Он централизует tint/opacity, blur, saturation, brightness, gradient rim и shadow. Его используют только modal `Window` и modeless draggable Inspector; обычные Launcher/SEO панели остаются непрозрачными. Настройки применяются через `applyGlassMaterial`, поэтому consumer не пересобирает CSS материала вручную. +`GlassMaterialSurface` — отдельный переносимый контракт Engine Glass V4. Он централизует tint/opacity, blur, saturation, brightness, gradient rim и shadow. Его используют только modal `Window` и modeless draggable Inspector; обычные Launcher/SEO панели остаются непрозрачными. Сам `Window` всегда получает класс `nodedc-glass-material` и `data-material="glass-v4"`, поэтому sharing, confirmation и остальные modal-паттерны физически используют тот же surface, что Inspector и лабораторный preview. Настройки применяются через `applyGlassMaterial`, поэтому consumer не пересобирает CSS материала вручную. ## Button и IconButton diff --git a/packages/tokens/themes.css b/packages/tokens/themes.css index 1c78da4..1f5c999 100644 --- a/packages/tokens/themes.css +++ b/packages/tokens/themes.css @@ -58,7 +58,7 @@ --nodedc-primary-action-color: rgb(var(--nodedc-on-accent-rgb)); --nodedc-primary-action-shadow: 0 12px 28px rgb(var(--nodedc-accent-rgb) / 0.2); --nodedc-modal-glass-tint-rgb: 11 11 14; - --nodedc-modal-glass-tint-opacity: 0.54; + --nodedc-modal-glass-tint-opacity: 0.94; --nodedc-modal-surface: linear-gradient(180deg, rgba(255, 255, 255, 0.068), rgba(255, 255, 255, 0.02)), rgb(var(--nodedc-modal-glass-tint-rgb) / var(--nodedc-modal-glass-tint-opacity)); --nodedc-modal-shadow: 0 34px 120px rgb(0 0 0 / var(--nodedc-modal-glass-shadow-opacity)), 0 10px 32px rgba(0, 0, 0, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.045); --nodedc-floating-surface: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012)), rgba(10, 10, 13, 0.94); @@ -123,7 +123,7 @@ --nodedc-primary-action-color: rgba(247, 248, 244, 0.96); --nodedc-primary-action-shadow: none; --nodedc-modal-glass-tint-rgb: 255 255 255; - --nodedc-modal-glass-tint-opacity: 0.72; + --nodedc-modal-glass-tint-opacity: 0.94; --nodedc-modal-surface: linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(255, 255, 255, 0.36)), rgb(var(--nodedc-modal-glass-tint-rgb) / var(--nodedc-modal-glass-tint-opacity)); --nodedc-modal-shadow: 0 24px 72px rgb(0 0 0 / var(--nodedc-modal-glass-shadow-light-opacity)), inset 0 1px 0 rgba(255, 255, 255, 0.8); --nodedc-floating-surface: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(255, 255, 255, 0.72)), rgba(255, 255, 255, 0.94); diff --git a/packages/tokens/tokens.css b/packages/tokens/tokens.css index acc2b4a..e70c435 100644 --- a/packages/tokens/tokens.css +++ b/packages/tokens/tokens.css @@ -38,9 +38,9 @@ --nodedc-blur-control: 24px; --nodedc-blur-panel: 44px; - --nodedc-blur-modal: 64px; - --nodedc-modal-glass-saturation: 1.38; - --nodedc-modal-glass-brightness: 1.06; + --nodedc-blur-modal: 44px; + --nodedc-modal-glass-saturation: 1.12; + --nodedc-modal-glass-brightness: 1.05; --nodedc-modal-glass-outline-opacity: 0.11; --nodedc-modal-glass-outline-soft-opacity: 0.0495; --nodedc-modal-glass-shadow-opacity: 0.64; diff --git a/packages/ui-core/src/glass.ts b/packages/ui-core/src/glass.ts index c4e13a0..a3ccac8 100644 --- a/packages/ui-core/src/glass.ts +++ b/packages/ui-core/src/glass.ts @@ -1,4 +1,5 @@ export interface GlassMaterialSettings { + version?: 4; tintHex: string; tintOpacity: number; blur: number; @@ -9,11 +10,12 @@ export interface GlassMaterialSettings { } export const defaultGlassMaterial: GlassMaterialSettings = { + version: 4, tintHex: "#0b0b0e", - tintOpacity: 54, - blur: 64, - saturation: 138, - brightness: 106, + tintOpacity: 94, + blur: 44, + saturation: 112, + brightness: 105, outlineOpacity: 11, shadowOpacity: 64, }; diff --git a/packages/ui-core/styles.css b/packages/ui-core/styles.css index 01f5b37..54c9cd6 100644 --- a/packages/ui-core/styles.css +++ b/packages/ui-core/styles.css @@ -1911,11 +1911,6 @@ textarea.nodedc-field__control { overflow: hidden; border: 0; border-radius: var(--nodedc-radius-modal); - background: var(--nodedc-modal-surface); - color: var(--nodedc-text-primary); - box-shadow: var(--nodedc-modal-shadow); - backdrop-filter: blur(var(--nodedc-blur-modal)) saturate(var(--nodedc-modal-glass-saturation)) brightness(var(--nodedc-modal-glass-brightness)); - -webkit-backdrop-filter: blur(var(--nodedc-blur-modal)) saturate(var(--nodedc-modal-glass-saturation)) brightness(var(--nodedc-modal-glass-brightness)); animation: nodedc-window-in var(--nodedc-duration-normal) var(--nodedc-ease-standard); } @@ -1931,14 +1926,9 @@ textarea.nodedc-field__control { width: min(var(--nodedc-inspector-width), calc(100vw - 3rem)); max-height: calc(100vh - 7.25rem); border-radius: var(--nodedc-radius-panel); - background: var(--nodedc-modal-surface); - box-shadow: var(--nodedc-modal-shadow); - backdrop-filter: blur(var(--nodedc-blur-modal)) saturate(var(--nodedc-modal-glass-saturation)) brightness(var(--nodedc-modal-glass-brightness)); - -webkit-backdrop-filter: blur(var(--nodedc-blur-modal)) saturate(var(--nodedc-modal-glass-saturation)) brightness(var(--nodedc-modal-glass-brightness)); pointer-events: auto; } -.nodedc-window::before, .nodedc-glass-material::before { position: absolute; z-index: -1; diff --git a/packages/ui-react/src/Window.tsx b/packages/ui-react/src/Window.tsx index 6700a0d..517cdb0 100644 --- a/packages/ui-react/src/Window.tsx +++ b/packages/ui-react/src/Window.tsx @@ -151,7 +151,8 @@ export function Window({