From 27407b905b1a9a513242428db6ecf9cdde214564 Mon Sep 17 00:00:00 2001 From: Navya-1314 Date: Fri, 7 Aug 2026 19:44:31 +0530 Subject: [PATCH] fix(layout): prioritise chart height across all laptop resolutions Invert center-column flex so chart grows to fill space (flex:1 1 0) while the Execution Feed becomes a compact fixed strip (flex:0 0 var(--feed-h)). OrderTicket now also flexes to fill its column, matching chart height exactly, and OrderJourney uses the same feed-h variable - satisfying the same-height requirement for Book/Chart/Ticket across all breakpoints. - Replace --chart-h and --ticket-h with a single --feed-h variable - Add CSS vars for pipeline/NBBO chrome density (pipeline-pad-y, pipeline-inner-gap, pipeline-node-size, nbbo-pad-y) - Tag pipeline subtext .pipeline-node-sub; hide at <=1440px to reclaim ~10px - workspace overflow set to hidden; no workspace-level scroll bar - Height breakpoints (800px/720px) tighten dock and feed further Tested: 1920x1080 / 1600x900 / 1536x864 / 1440x900 / 1366x768 / 1280x720 --- frontend/src/components/NBBOBar.tsx | 2 +- frontend/src/components/SystemPipeline.tsx | 8 +- frontend/src/index.css | 95 +++++++++++++++------- 3 files changed, 69 insertions(+), 36 deletions(-) diff --git a/frontend/src/components/NBBOBar.tsx b/frontend/src/components/NBBOBar.tsx index 0ef9bd0..d1729d2 100644 --- a/frontend/src/components/NBBOBar.tsx +++ b/frontend/src/components/NBBOBar.tsx @@ -28,7 +28,7 @@ export function NBBOBar({ bestBid, bestAsk, spread, symbol, isConnected }: Props style={{ background: 'var(--bg-secondary)', borderBottom: '1px solid var(--border-color)', - padding: '4px 16px', + padding: 'var(--nbbo-pad-y, 4px) var(--pad-x, 16px)', display: 'flex', alignItems: 'center', gap: '20px', diff --git a/frontend/src/components/SystemPipeline.tsx b/frontend/src/components/SystemPipeline.tsx index 286fbed..4611403 100644 --- a/frontend/src/components/SystemPipeline.tsx +++ b/frontend/src/components/SystemPipeline.tsx @@ -194,7 +194,7 @@ export const SystemPipeline: React.FC = ({ lifecycle, isCon
= ({ lifecycle, isCon }} > {/* Header */} -
+
@@ -283,7 +283,7 @@ export const SystemPipeline: React.FC = ({ lifecycle, isCon ref={el => { nodeRefs.current[idx] = el; }} className={extraClass} style={{ - width: '24px', height: '24px', borderRadius: '50%', + width: 'var(--pipeline-node-size, 24px)', height: 'var(--pipeline-node-size, 24px)', borderRadius: '50%', background: bgCol, border: `1.5px solid ${borderCol}`, display: 'flex', alignItems: 'center', justifyContent: 'center', @@ -320,7 +320,7 @@ export const SystemPipeline: React.FC = ({ lifecycle, isCon {/* Subtext */} - .terminal-panel { + overflow-y: auto; } .workspace-panel--ticket { - flex: 0 1 var(--ticket-h); - height: var(--ticket-h); - max-height: var(--ticket-h); + flex: 1 1 0; + min-height: 160px; overflow: hidden; } -.workspace-panel--ticket .terminal-panel { - overflow: auto; +.workspace-panel--ticket > .terminal-panel { + overflow-y: auto; } .workspace-panel--journey { - flex: 1 1 auto; - min-height: 100px; + flex: 0 0 var(--feed-h); + min-height: 0; + overflow: hidden; +} + +.workspace-panel--journey > .terminal-panel { + overflow-y: auto; } .bottom-dock { @@ -478,7 +492,8 @@ select.input-field { } /* ─── Responsive density breakpoints ─────────────────────────────────────────── */ -/* 1600×900 and similar */ + +/* 1600×900 — first density tier */ @media (max-width: 1600px) { :root { --col-left: 240px; @@ -487,13 +502,16 @@ select.input-field { --pad-x: 12px; --pad-y: 10px; --dock-h: clamp(150px, 24vh, 230px); - --chart-h: clamp(110px, 18vh, 155px); - --ticket-h: clamp(190px, 28vh, 250px); + --feed-h: 125px; + --pipeline-pad-y: 6px; + --pipeline-inner-gap: 5px; + --pipeline-node-size: 22px; + --nbbo-pad-y: 3px; --ui-scale: 0.96; } } -/* 1440×900 */ +/* 1440×900 / 1366×768 — pipeline subtext hidden to reclaim ~10px of chrome */ @media (max-width: 1440px) { :root { --col-left: 220px; @@ -503,8 +521,11 @@ select.input-field { --pad-y: 8px; --header-h: 48px; --dock-h: clamp(140px, 24vh, 210px); - --chart-h: clamp(100px, 17vh, 145px); - --ticket-h: clamp(180px, 28vh, 240px); + --feed-h: 112px; + --pipeline-pad-y: 5px; + --pipeline-inner-gap: 4px; + --pipeline-node-size: 20px; + --nbbo-pad-y: 3px; --ui-scale: 0.93; } @@ -512,9 +533,14 @@ select.input-field { grid-template-columns: minmax(140px, 180px) minmax(0, 1fr); gap: 14px; } + + /* Hide per-node timing subtext — saves ~10px of pipeline height */ + .pipeline-node-sub { + display: none; + } } -/* 1366×768 / 1536×864 / 1280×720 */ +/* 1536×864 / 1366×768 / 1280×720 */ @media (max-width: 1280px) { :root { --col-left: 200px; @@ -525,8 +551,11 @@ select.input-field { --header-h: 46px; --tab-h: 28px; --dock-h: clamp(130px, 26vh, 190px); - --chart-h: clamp(96px, 16vh, 130px); - --ticket-h: clamp(170px, 30vh, 220px); + --feed-h: 100px; + --pipeline-pad-y: 4px; + --pipeline-inner-gap: 3px; + --pipeline-node-size: 18px; + --nbbo-pad-y: 2px; --ui-scale: 0.9; } @@ -554,24 +583,28 @@ select.input-field { } } -/* Short laptop viewports — keep chrome + dock, let workspace scroll */ +/* Height breakpoint — 1366×768 and similar short laptops */ @media (max-height: 800px) { :root { --dock-h: clamp(120px, 22vh, 180px); - --chart-h: clamp(90px, 15vh, 130px); - --ticket-h: clamp(160px, 28vh, 220px); + --feed-h: 100px; } .workspace { - grid-template-rows: minmax(220px, 1fr); + grid-template-rows: minmax(200px, 1fr); } } +/* Height breakpoint — 1280×720 extreme compact */ @media (max-height: 720px) { :root { --dock-h: clamp(110px, 20vh, 160px); - --chart-h: clamp(80px, 14vh, 120px); - --ticket-h: clamp(150px, 26vh, 200px); + --feed-h: 88px; --header-h: 44px; + --pipeline-pad-y: 3px; + --pipeline-inner-gap: 2px; + --pipeline-node-size: 16px; + --nbbo-pad-y: 2px; } } +