fix(ui): stabilize responsive shell chrome
This commit is contained in:
parent
ce07c00513
commit
31d8932067
@ -191,18 +191,16 @@ function App() {
|
||||
showMarketplaceTab,
|
||||
handleSignOut,
|
||||
}}>
|
||||
{/* Critical system alert banner */}
|
||||
{hasCriticalEvents && (
|
||||
<div className="critical-alert-banner">
|
||||
<span>⚠️</span>
|
||||
<span>
|
||||
SYSTEM ALERT: {recentCriticalEvents.length} CRITICAL ISSUES DETECTED — GO TO SETTINGS › ADMIN PANEL
|
||||
</span>
|
||||
<span>⚠️</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<div className={`app-runtime${hasCriticalEvents ? ' has-critical-alert' : ''}`}>
|
||||
{hasCriticalEvents && (
|
||||
<a className="critical-alert-banner" href="/settings">
|
||||
<span aria-hidden="true">⚠️</span>
|
||||
<span>
|
||||
System alert: {recentCriticalEvents.length} critical issues detected — go to Settings › Admin Panel
|
||||
</span>
|
||||
<span aria-hidden="true">⚠️</span>
|
||||
</a>
|
||||
)}
|
||||
<AppShell />
|
||||
</div>
|
||||
|
||||
|
||||
@ -546,8 +546,8 @@ export const ChatControl = ({ profiles, botState, onApplyProfile }: ChatControlP
|
||||
variant="ghost"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
bottom: '24px',
|
||||
right: '24px',
|
||||
bottom: 'var(--trading-assistant-bottom, 24px)',
|
||||
right: 'var(--trading-assistant-right, 24px)',
|
||||
zIndex: 99999,
|
||||
cursor: 'pointer',
|
||||
background: 'none',
|
||||
@ -628,13 +628,13 @@ export const ChatControl = ({ profiles, botState, onApplyProfile }: ChatControlP
|
||||
/>
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
bottom: '24px',
|
||||
right: '24px',
|
||||
bottom: 'var(--trading-assistant-bottom, 24px)',
|
||||
right: 'var(--trading-assistant-right, 24px)',
|
||||
zIndex: 999999,
|
||||
width: '460px',
|
||||
maxWidth: 'calc(100vw - 48px)',
|
||||
maxWidth: 'calc(100vw - 32px)',
|
||||
height: '640px',
|
||||
maxHeight: 'calc(100vh - 48px)',
|
||||
maxHeight: 'calc(100dvh - var(--trading-assistant-bottom, 24px) - 16px)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
borderRadius: '20px',
|
||||
|
||||
@ -3,7 +3,7 @@ import { Link, Routes, Route, Navigate, useLocation } from 'react-router-dom';
|
||||
import { Sidebar } from './Sidebar';
|
||||
import { Header } from './Header';
|
||||
import { RightPanel } from './RightPanel';
|
||||
import { Button } from '../ui/Primitives';
|
||||
import { Button, Skeleton } from '../ui/Primitives';
|
||||
import { getLegacySimpleRoute, getPlansRoute } from '../../views/tradePlansRoutes';
|
||||
|
||||
const HomeView = lazy(() => import('../../views/HomeView').then((mod) => ({ default: mod.HomeView })));
|
||||
@ -22,8 +22,15 @@ function RouteFallback() {
|
||||
aria-live="polite"
|
||||
className="route-fallback route-fallback-inline"
|
||||
>
|
||||
<div className="route-fallback-spinner" aria-hidden="true" />
|
||||
<span>Loading workspace…</span>
|
||||
<div className="route-fallback-status">
|
||||
<div className="route-fallback-spinner" aria-hidden="true" />
|
||||
<span>Loading workspace…</span>
|
||||
</div>
|
||||
<div className="route-fallback-preview" aria-hidden="true">
|
||||
<Skeleton shape="text" className="route-fallback-title" />
|
||||
<Skeleton className="route-fallback-card" />
|
||||
<Skeleton className="route-fallback-card route-fallback-card-short" />
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@ -68,6 +68,12 @@
|
||||
--bl-radius-card: 0.875rem;
|
||||
--bl-input: var(--input);
|
||||
--bl-border-strong: var(--border-strong);
|
||||
--trading-shell-sidebar-width: 76px;
|
||||
--trading-shell-tablet-sidebar-width: 88px;
|
||||
--trading-shell-right-panel-width: 308px;
|
||||
--trading-shell-bottom-nav-height: 72px;
|
||||
--trading-assistant-bottom: 24px;
|
||||
--trading-assistant-right: 24px;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
@ -276,6 +282,11 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.app-runtime {
|
||||
min-height: 100vh;
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
.dashboard-shell {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
@ -286,7 +297,7 @@ body {
|
||||
}
|
||||
|
||||
.dashboard-main {
|
||||
margin-left: 72px;
|
||||
margin-left: var(--trading-shell-sidebar-width);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -299,6 +310,7 @@ body {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
@ -307,16 +319,17 @@ body {
|
||||
overflow-x: hidden;
|
||||
padding: 32px 32px 40px;
|
||||
min-width: 0;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
width: 308px;
|
||||
min-width: 308px;
|
||||
max-width: 308px;
|
||||
width: var(--trading-shell-right-panel-width);
|
||||
min-width: var(--trading-shell-right-panel-width);
|
||||
max-width: var(--trading-shell-right-panel-width);
|
||||
}
|
||||
|
||||
.trading-sidebar {
|
||||
width: 76px;
|
||||
width: var(--trading-shell-sidebar-width);
|
||||
min-height: 100vh;
|
||||
background: var(--sidebar);
|
||||
border-right: 1px solid var(--border);
|
||||
@ -407,12 +420,22 @@ body {
|
||||
}
|
||||
|
||||
.route-fallback-inline {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
min-height: min(420px, calc(100vh - 180px));
|
||||
gap: 12px;
|
||||
gap: 18px;
|
||||
padding: 24px;
|
||||
background: color-mix(in oklab, var(--card) 92%, var(--background));
|
||||
box-shadow: var(--card-shadow);
|
||||
}
|
||||
|
||||
.route-fallback-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.route-fallback-spinner {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
@ -422,6 +445,27 @@ body {
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
.route-fallback-preview {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
width: min(560px, 100%);
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.route-fallback-title {
|
||||
width: 46%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.route-fallback-card {
|
||||
min-height: 92px;
|
||||
}
|
||||
|
||||
.route-fallback-card-short {
|
||||
min-height: 64px;
|
||||
width: 78%;
|
||||
}
|
||||
|
||||
.route-empty-state {
|
||||
min-height: 420px;
|
||||
flex-direction: column;
|
||||
@ -1414,27 +1458,33 @@ body {
|
||||
}
|
||||
|
||||
.critical-alert-banner {
|
||||
position: sticky;
|
||||
top: 8px;
|
||||
z-index: 9999;
|
||||
position: relative;
|
||||
z-index: 80;
|
||||
display: flex;
|
||||
width: fit-content;
|
||||
max-width: min(860px, calc(100vw - 32px));
|
||||
margin: 10px auto 0;
|
||||
width: 100%;
|
||||
min-height: 44px;
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
border: 1px solid color-mix(in oklab, var(--destructive) 28%, var(--border));
|
||||
border-radius: 18px;
|
||||
background: color-mix(in oklab, var(--card) 92%, var(--destructive));
|
||||
border: 0;
|
||||
border-bottom: 1px solid color-mix(in oklab, var(--destructive) 26%, var(--border));
|
||||
background: color-mix(in oklab, var(--card) 88%, var(--destructive));
|
||||
color: var(--destructive);
|
||||
padding: 8px 18px;
|
||||
padding: 9px 18px;
|
||||
text-align: center;
|
||||
box-shadow: 0 14px 34px rgba(15, 23, 42, 0.10);
|
||||
font-size: 10px;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 10px 28px rgba(15, 23, 42, 0.08);
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.critical-alert-banner:hover {
|
||||
background: color-mix(in oklab, var(--card) 82%, var(--destructive));
|
||||
color: var(--destructive);
|
||||
}
|
||||
|
||||
.trade-plans-page > .grid {
|
||||
@ -1907,6 +1957,224 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Final chrome overrides: keep navigation, alerts, content, and assistant from colliding. */
|
||||
@media (max-width: 1279px) {
|
||||
.dashboard-main {
|
||||
margin-left: var(--trading-shell-tablet-sidebar-width);
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
--trading-shell-right-panel-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 561px) and (max-width: 1023px) {
|
||||
.dashboard-shell {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.dashboard-main {
|
||||
margin-left: var(--trading-shell-tablet-sidebar-width);
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
padding: 24px 20px 36px;
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.trading-sidebar {
|
||||
top: 0;
|
||||
right: auto;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: var(--trading-shell-tablet-sidebar-width);
|
||||
height: auto;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 16px 8px;
|
||||
border-top: 0;
|
||||
border-right: 1px solid var(--border);
|
||||
overflow-x: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
:root {
|
||||
--trading-assistant-bottom: calc(var(--trading-shell-bottom-nav-height) + 18px);
|
||||
--trading-assistant-right: 16px;
|
||||
}
|
||||
|
||||
.critical-alert-banner {
|
||||
min-height: 52px;
|
||||
padding: 8px 16px;
|
||||
font-size: 11px;
|
||||
line-height: 1.45;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.dashboard-shell {
|
||||
padding-bottom: var(--trading-shell-bottom-nav-height);
|
||||
}
|
||||
|
||||
.dashboard-main {
|
||||
margin-left: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
padding: 18px 16px calc(var(--trading-shell-bottom-nav-height) + 28px);
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.trading-sidebar {
|
||||
width: 100%;
|
||||
min-height: var(--trading-shell-bottom-nav-height);
|
||||
height: var(--trading-shell-bottom-nav-height);
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
padding: 0 max(8px, env(safe-area-inset-left)) env(safe-area-inset-bottom) max(8px, env(safe-area-inset-right));
|
||||
border-right: 0;
|
||||
border-top: 1px solid var(--border);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.trading-sidebar-nav {
|
||||
flex: 0 1 auto;
|
||||
flex-direction: row;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.trading-sidebar-link {
|
||||
width: 68px;
|
||||
min-width: 68px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Central shell sizing shared by the final breakpoint rules below. */
|
||||
@media (max-width: 1279px) {
|
||||
.dashboard-main {
|
||||
margin-left: var(--trading-shell-tablet-sidebar-width);
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
--trading-shell-right-panel-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 561px) and (max-width: 1023px) {
|
||||
.dashboard-shell {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.dashboard-main {
|
||||
margin-left: var(--trading-shell-tablet-sidebar-width);
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
padding: 24px 20px 36px;
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.trading-sidebar {
|
||||
top: 0;
|
||||
right: auto;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: var(--trading-shell-tablet-sidebar-width);
|
||||
height: auto;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 16px 8px;
|
||||
border-top: 0;
|
||||
border-right: 1px solid var(--border);
|
||||
overflow-x: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
:root {
|
||||
--trading-assistant-bottom: calc(var(--trading-shell-bottom-nav-height) + 18px);
|
||||
--trading-assistant-right: 16px;
|
||||
}
|
||||
|
||||
.critical-alert-banner {
|
||||
min-height: 52px;
|
||||
padding: 8px 16px;
|
||||
font-size: 11px;
|
||||
line-height: 1.45;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.dashboard-shell {
|
||||
padding-bottom: var(--trading-shell-bottom-nav-height);
|
||||
}
|
||||
|
||||
.dashboard-main {
|
||||
margin-left: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
padding: 18px 16px calc(var(--trading-shell-bottom-nav-height) + 28px);
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.trading-sidebar {
|
||||
width: 100%;
|
||||
min-height: var(--trading-shell-bottom-nav-height);
|
||||
height: var(--trading-shell-bottom-nav-height);
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
padding: 0 max(8px, env(safe-area-inset-left)) env(safe-area-inset-bottom) max(8px, env(safe-area-inset-right));
|
||||
border-right: 0;
|
||||
border-top: 1px solid var(--border);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.trading-sidebar-nav {
|
||||
flex: 0 1 auto;
|
||||
flex-direction: row;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.trading-sidebar-link {
|
||||
width: 68px;
|
||||
min-width: 68px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.markets-opportunity-grid,
|
||||
.screener-filter-row {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user