/* N7 Web Console design-system contract. * Loaded last by Vite so every legacy surface consumes one geometry, * typography, state and elevation scale while the runtime is migrated to * Vue components incrementally. */ :root { --n7-control-height-sm: 32px; --n7-control-height: 38px; --n7-icon-button-size: 38px; --n7-radius-control: 10px; --n7-radius-card: 14px; --n7-radius-section: 16px; --n7-radius-panel: 18px; --n7-radius-dialog: 22px; --n7-font-caption: 12px; --n7-font-body: 13px; --n7-font-card-title: 14px; --n7-font-panel-title: 16px; --n7-font-dialog-title: 22px; --n7-shadow-card: inset 0 1px 0 var(--glass-highlight), 0 7px 20px color-mix(in oklch, var(--foreground) 8%, transparent); --n7-shadow-panel: inset 0 1px 0 var(--glass-highlight), 0 14px 34px color-mix(in oklch, var(--foreground) 13%, transparent); --n7-shadow-dialog: inset 0 1px 0 var(--glass-highlight), 0 28px 84px color-mix(in oklch, var(--foreground) 28%, transparent); } #app { min-width: inherit; min-height: 100dvh; display: contents; } /* Workspace panels: one top-level geometry, distinct from their children. */ body.console-v2.v2-passive-display.v2-interactive-sync :is( .main-panel > .v2-mode-rail, #assistantDrawer, .joint-twin-shell > .twin-band, #v2DevicePanel, #v2ExtensionPanel .v2-extension-sync-mount ) { border-radius: var(--n7-radius-panel) !important; box-shadow: var(--n7-shadow-panel) !important; } body.console-v2 :is( .v2-sync-transport-field, .v2-sync-execution-field, .v2-can-command-panel, .v2-control-link-card, .v2-nfc-inline, .v2-extension-gateway, .v2-extension-synced-device, .v2-extension-empty, .v2-pet-card, .v2-pet-presence-card, .v2-device-card, .v2-synced-device, .mode-gallery-card, .mode-editor-command-card, .energy-kpi, .energy-device-row, .assistant-dispatched-controls, .assistant-mode-draft, .assistant-mode-created, .assistant-control-suggestion ) { border-radius: var(--n7-radius-card) !important; box-shadow: var(--n7-shadow-card) !important; } body.console-v2 :is( .v2-sync-log, .v2-pet-card-region, .mode-gallery-group, .mode-editor-flow, .v2-nfc-stage, .energy-trend-card, .energy-devices-card ) { border-radius: var(--n7-radius-section) !important; } /* Only actionable cards float. Read-only panels remain spatially stable. */ body.console-v2 :is( .v2-sync-log, .v2-pet-card-region, .mode-editor-flow, .energy-trend-card, .energy-devices-card ):is(:hover, :focus-within) { transform: none !important; box-shadow: var(--n7-shadow-card) !important; } /* The current DOM uses .twin-selector; the previous glass selector targeted * the removed .twin-seat-switch class and produced white-on-white tabs. */ body.console-v2 .joint-twin-shell :is(.twin-selector, .twin-selector button, .twin-reset, .twin-focus-badge) { color: var(--muted-foreground) !important; background: var(--glass-card) !important; border-color: var(--glass-line) !important; box-shadow: inset 0 1px 0 var(--glass-highlight) !important; } body.console-v2 .joint-twin-shell .twin-selector button.active { color: var(--primary-foreground) !important; background: var(--primary) !important; border-color: color-mix(in oklch, var(--primary) 72%, white 18%) !important; } /* Shared heading hierarchy. */ body.console-v2 :is( #assistantDrawer h2, .joint-twin-shell .twin-heading h3, .v2-device-sync-board > header h3, .v2-extension-sync-heading h3, .v2-mode-rail .mode-rail-title ) { font-size: var(--n7-font-panel-title) !important; font-weight: 750 !important; line-height: 1.25 !important; letter-spacing: -0.02em; } /* The log title shares a 217 px header with its filter, so it needs the * compact card-title scale instead of the full panel-title scale. */ body.console-v2 .v2-sync-log h3 { min-width: 0; margin: 0; overflow: hidden; font-size: var(--n7-font-card-title) !important; font-weight: 750 !important; line-height: 1.25 !important; letter-spacing: -0.02em; text-overflow: ellipsis; white-space: nowrap; } /* Sidebar disclosure, connection status and control-command readability use * the same semantic tokens in both day and night themes. */ body.console-v2 .v2-sync-log[data-collapsed="true"] { min-height: 0; align-self: start; grid-template-rows: auto; flex: 0 0 auto; } body.console-v2 .v2-sync-log[data-collapsed="true"] > header { border-bottom-color: transparent; } body.console-v2 .v2-sync-log[data-collapsed="true"] #v2LogFilter { display: none; } body.console-v2 .v2-sync-log #v2SyncLogList[hidden] { display: none !important; } body.console-v2 .v2-sync-log > header > div:first-child { min-width: 0; } body.console-v2 .v2-sync-log .v2-sync-log-actions { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 6px; } body.console-v2 .v2-sync-log .v2-sync-log-toggle { min-width: 46px; min-height: var(--n7-control-height-sm); display: inline-flex; align-items: center; justify-content: center; gap: 4px; padding: 0 7px; color: var(--muted-foreground); background: var(--secondary); border: 1px solid var(--input); border-radius: var(--n7-radius-control); cursor: pointer; } body.console-v2 .v2-sync-log .v2-sync-log-toggle:is(:hover, :focus-visible) { color: var(--accent-foreground); background: var(--accent); border-color: var(--ring); outline: none; } body.console-v2 .v2-sync-log .v2-sync-log-toggle svg { width: 15px; height: 15px; transition: transform 160ms ease; } body.console-v2 .v2-sync-log .v2-sync-log-toggle[aria-expanded="true"] svg { transform: rotate(180deg); } body.console-v2.v2-passive-display.v2-interactive-sync .v2-control-link-card { min-height: 56px; grid-template-columns: 10px minmax(0, 1fr); gap: 10px; margin: 0 !important; padding: 10px 11px !important; color: var(--card-foreground); background: var(--glass-card) !important; border: 1px solid var(--glass-line) !important; border-radius: var(--n7-radius-card) !important; box-shadow: var(--n7-shadow-card) !important; -webkit-backdrop-filter: blur(16px) saturate(1.2); backdrop-filter: blur(16px) saturate(1.2); } body.console-v2 .v2-control-link-card strong { color: var(--card-foreground) !important; } body.console-v2 .v2-control-link-card small { color: var(--muted-foreground) !important; } body.console-v2 .v2-control-link-card[data-state="online"] .v2-live-dot { background: var(--status-online); box-shadow: 0 0 0 4px color-mix(in oklch, var(--status-online) 18%, transparent); } body.console-v2 .v2-control-link-card[data-state="connecting"] .v2-live-dot { background: var(--status-info); box-shadow: 0 0 0 4px color-mix(in oklch, var(--status-info) 18%, transparent); } body.console-v2 .v2-control-link-card[data-state="degraded"] .v2-live-dot { background: var(--status-warning); box-shadow: 0 0 0 4px color-mix(in oklch, var(--status-warning) 18%, transparent); } body.console-v2 .v2-control-link-card[data-state="offline"] .v2-live-dot { background: var(--status-offline); box-shadow: 0 0 0 4px color-mix(in oklch, var(--status-offline) 18%, transparent); } body.console-v2.v2-passive-display.v2-interactive-sync .v2-can-command-list li[data-can-channel] .v2-can-command-actual code { color: var(--card-foreground) !important; } body.console-v2 :is( .mode-gallery-header h2, .mode-editor-header h2, .v2-extension-dialog > header h2, .v2-extension-dialog form > header h2, .energy-monitor-heading h2 ) { font-size: var(--n7-font-dialog-title) !important; font-weight: 750 !important; line-height: 1.2 !important; } body.console-v2 :is( .mode-gallery-card-heading strong, .v2-device-card-focus strong, .v2-nfc-inline strong, .v2-extension-gateway strong, .v2-pet-card > header > strong, .energy-trend-card h3, .energy-devices-card h3 ) { font-size: var(--n7-font-card-title) !important; line-height: 1.35 !important; } body.console-v2 :is( .mode-editor-status, .mode-gallery-footer, .v2-pet-settings-footnote, .v2-pet-card-fields > label > span, .v2-pet-nfc-field output, .energy-kpi > small, .energy-kpi > em, .energy-devices-card > footer ) { font-size: var(--n7-font-caption) !important; line-height: 1.45 !important; } /* One dialog radius, elevation and close-button size. */ body.console-v2 :is( .mode-gallery, .mode-editor, .v2-nfc-dialog, .v2-gscu-tcp-dialog, .v2-pet-settings-dialog, .energy-monitor-page ) { border-radius: var(--n7-radius-dialog) !important; box-shadow: var(--n7-shadow-dialog) !important; } body.console-v2 :is( .mode-gallery-close, .mode-editor-header > button, .v2-extension-dialog [data-dialog-close], .v2-extension-dialog [data-close-extension-dialog], .v2-extension-dialog [data-close-nfc-dialog], #energyMonitorClose ) { width: var(--n7-icon-button-size) !important; height: var(--n7-icon-button-size) !important; min-width: var(--n7-icon-button-size); min-height: var(--n7-icon-button-size); border-radius: var(--n7-radius-control) !important; } /* Compact icon actions still meet a usable hit target without becoming a * second visual system. */ body.console-v2 :is( .twin-reset, .mode-gallery-edit, .mode-gallery-delete, .v2-pet-card > header > button ) { width: var(--n7-control-height-sm) !important; height: var(--n7-control-height-sm) !important; min-width: var(--n7-control-height-sm); min-height: var(--n7-control-height-sm); border-radius: var(--n7-radius-control) !important; } /* Offline hardware is a destructive state, not a primary/active state. */ body.console-v2 .v2-nfc-stage:has(.v2-nfc-waiting.offline) > header { color: var(--status-error-foreground) !important; background: color-mix(in oklch, var(--destructive) 16%, var(--card)) !important; border-bottom: 1px solid color-mix(in oklch, var(--destructive) 32%, var(--border)); } body.console-v2 .v2-nfc-stage:has(.v2-nfc-waiting.offline) > header :is(span, small, h3, p, b) { color: var(--status-error-foreground) !important; } /* Keep the global appearance control out of content and below every modal. */ .glass-theme-toggle { left: max(18px, env(safe-area-inset-left)) !important; bottom: max(18px, env(safe-area-inset-bottom)) !important; z-index: 1100 !important; } body.mode-gallery-open .glass-theme-toggle, body.mode-editor-open .glass-theme-toggle, body:has(.v2-extension-dialog[open]) .glass-theme-toggle, body:has(.energy-monitor-layer:not([hidden])) .glass-theme-toggle { opacity: 0; pointer-events: none; } /* The sidebar reserves the floating control's footprint instead of allowing * it to cover the log timeline. */ body.console-v2 .v2-sync-log { margin-bottom: 58px; } /* Top mode rail communicates that more content is available. */ body.console-v2 .v2-mode-rail .mode-rail-content { position: relative; min-width: 0; } body.console-v2 .v2-mode-rail .mode-rail-content::after { width: 28px; content: ""; position: absolute; inset: 0 0 0 auto; pointer-events: none; background: linear-gradient(90deg, transparent, color-mix(in oklch, var(--glass-panel) 94%, transparent)); } @media (max-width: 1360px) { .glass-theme-toggle { width: 42px !important; height: 42px !important; } } @media (prefers-reduced-motion: reduce) { body.console-v2 * { scroll-behavior: auto !important; } }