Repository navigation
Expand file tree
/
Copy pathlayout.css
More file actions
206 lines (196 loc) · 7.74 KB
/
Copy pathlayout.css
File metadata and controls
206 lines (196 loc) · 7.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/* =========================================================================
layout.css — Speculum page layout (grid + top bar).
Material lives in tokens.css/components.css; layout lives here.
Deck: centred, max-width 1720 px, 24 px side padding, 12 columns.
Collapses at 1440 / 1024 / 768 px.
========================================================================= */
/* --- deck grid ------------------------------------------------------------- */
.deck {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
/* dense: backfill the Context panel into the slot beside Throughput even
though GPU & host comes first in the DOM (and the ledger beside GPU) */
grid-auto-flow: dense;
gap: var(--sp-3);
width: min(1720px, 100%);
margin: 0 auto;
padding: var(--sp-3) 24px var(--sp-5);
}
/* section shells (filled by panel modules in app.js). Context residency is
the signature panel: it sits next to Throughput on the top row, and GPU &
host moved down beside the token ledger. */
.g-kpi { grid-column: 1 / -1; }
.g-throughput { grid-column: 1 / 8; }
.g-context { grid-column: 8 / 13; }
.g-timeline { grid-column: 1 / -1; }
.g-gpu { grid-column: 1 / 5; }
.g-ledger { grid-column: 5 / 9; }
.g-storage { grid-column: 9 / 13; }
.g-requests { grid-column: 1 / -1; }
.g-leader { grid-column: 1 / -1; }
.g-events { grid-column: 1 / 8; }
.g-pool { grid-column: 8 / 13; }
/* engines: one card per engine, from the registry */
.g-engines {
grid-column: 1 / -1;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: var(--sp-3);
align-content: start;
}
/* --- row stretching (DESIGN.md §3: no panel leaves dead space beside a taller
neighbour at 1440 / 1024 / 768 px) ------------------------------------------ */
/* A shell stretches to its grid row by default; make it pass that height down
to its panel, and the panel body takes whatever the header does not use, so
charts and tile areas fill the row instead of leaving a gap under a shorter
neighbour (throughput/context, GPU/ledger, events/pool). The engines shell is
itself a card grid, so it is not flexed here. Applies to both views. */
.deck > section:not(.g-engines) { display: flex; }
.deck > section > .panel { flex: 1 1 auto; }
/* --- Basic view (the class is set on #deck by app.js) ------------------------ */
/* Basic shows KPI, throughput, GPU & host and engines; the five Advanced-only
shells are display:none, so the areas below hold no empty cell. */
.deck.view-basic {
grid-template-areas:
"kpi kpi kpi kpi kpi kpi kpi kpi kpi kpi kpi kpi"
"tp tp tp tp tp tp gpu gpu gpu gpu gpu gpu"
"tl tl tl tl tl tl tl tl tl tl tl tl"
"eng eng eng eng eng eng eng eng eng eng eng eng";
}
.deck.view-basic .g-kpi { grid-area: kpi; }
.deck.view-basic .g-throughput { grid-area: tp; }
.deck.view-basic .g-gpu { grid-area: gpu; }
.deck.view-basic .g-engines { grid-area: eng; }
.deck.view-basic .g-timeline { grid-area: tl; }
.deck.view-basic .g-storage,
.deck.view-basic .g-leader,
.deck.view-basic .g-context,
.deck.view-basic .g-ledger,
.deck.view-basic .g-requests,
.deck.view-basic .g-events,
.deck.view-basic .g-pool { display: none; }
/* --- top bar (48px, full-bleed hairline over the centred deck) -------------- */
.topbar {
position: sticky;
top: 0;
z-index: 40;
display: flex;
align-items: center;
gap: var(--sp-3);
height: 48px;
padding: 0 24px;
background: var(--surface-1);
border-bottom: 1px solid var(--border);
}
.topbar .brand {
display: flex;
align-items: baseline;
gap: var(--sp-2);
margin-right: var(--sp-2);
white-space: nowrap;
}
.topbar .brand b {
font-family: var(--font-display);
font-size: 15px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--text-1);
}
.topbar .brand span { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; text-transform: lowercase; color: var(--text-3); }
.topbar .spacer { flex: 1; }
.topbar .cluster {
display: flex;
align-items: center;
gap: var(--sp-4);
min-width: 0;
}
.topbar .cluster .kv {
display: inline-flex;
align-items: baseline;
gap: var(--sp-1);
font-size: var(--fs-meta);
color: var(--text-3);
white-space: nowrap;
}
.topbar .cluster .kv b {
font-size: var(--fs-label);
font-weight: 500;
color: var(--text-1);
font-variant-numeric: tabular-nums;
overflow: hidden;
text-overflow: ellipsis;
max-width: 220px;
}
/* --- foot --------------------------------------------------------------------- */
.foot {
width: min(1720px, 100%);
margin: 0 auto;
padding: 0 24px var(--sp-4);
font-size: var(--fs-meta);
color: var(--text-3);
}
.foot kbd {
font-family: var(--font-mono);
font-size: var(--fs-meta);
padding: 1px 5px;
border: 1px solid var(--border);
border-radius: var(--r-ctl);
background: var(--surface-2);
}
/* --- responsive ------------------------------------------------------------------ */
/* 1440 px: the deck is still full-width here (cap 1720) — only KPI spacing
tightens (components.css); the grid stays 12 columns */
@media (max-width: 1024px) {
/* (grid-auto-flow: dense from the base rule keeps GPU + ledger packed
beside each other when the full-width Context panel skips their row) */
.deck { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.g-throughput,
.g-context, /* signature panel keeps the full row at 6 columns */
.g-events,
.g-pool { grid-column: 1 / 7; }
.g-gpu { grid-column: 1 / 4; }
.g-ledger { grid-column: 4 / 7; }
.g-storage { grid-column: 1 / 7; } /* its own row at 6 columns, GPU + ledger keep theirs */
/* Basic at 6 columns: KPI full row, throughput + GPU share one (3 + 3),
engines full row — nothing left empty */
.deck.view-basic {
grid-template-areas:
"kpi kpi kpi kpi kpi kpi"
"tp tp tp gpu gpu gpu"
"tl tl tl tl tl tl"
"eng eng eng eng eng eng";
}
}
/* Below 1024 px the one-row bar no longer fits the status cluster: it wraps to rows instead of the
cluster scrolling sideways, which had pushed the Basic/Advanced toggle off-screen (769-1023 px
as well as phone width). */
@media (max-width: 1023px) {
.topbar { flex-wrap: wrap; height: auto; min-height: 48px; row-gap: var(--sp-2); }
.topbar .brand { flex: 1 1 100%; }
.topbar .spacer { display: none; }
.topbar .cluster { flex: 1 1 100%; flex-wrap: wrap; }
.topbar .cluster > .segmented { margin-left: auto; }
}
@media (max-width: 768px) {
/* minmax(0, 1fr), not 1fr: a bare 1fr track never shrinks below its widest
table, which pushed the whole deck to ~535 px on a 390 px phone */
.deck { grid-template-columns: minmax(0, 1fr); padding: var(--sp-2) var(--sp-3) var(--sp-4); }
/* wide tables scroll inside their panel instead of the page scrolling */
.table-wrap { overflow-x: auto; overscroll-behavior-x: contain; }
/* the bar wraps to rows instead of the cluster scrolling sideways: a scrolling
cluster pushed the Basic/Advanced toggle off-screen at phone width. Brand on
its own row, the cluster below it, and the toggle is the item that wraps onto
a row of its own — nothing is clipped, so the page never scrolls sideways.
Above 768 px the bar stays a single 48 px row. */
.g-kpi, .g-throughput, .g-gpu, .g-context, .g-ledger, .g-timeline, .g-storage, .g-leader,
.g-requests, .g-engines, .g-events, .g-pool { grid-column: 1 / -1; }
.g-engines { grid-template-columns: 1fr; }
/* Basic at one column: four stacked rows, in DOM order */
.deck.view-basic { grid-template-areas: "kpi" "tp" "gpu" "tl" "eng"; }
.topbar { gap: var(--sp-2); padding: 0 var(--sp-2); }
.topbar .brand span { display: none; }
.topbar .cluster { gap: var(--sp-2); }
.topbar .cluster .kv b { max-width: 90px; }
.topbar .hide-sm { display: none; }
}