Skip to content

Commit 65b996b

Browse files
committed
ALFA 003 toolbox status bar single row polish
1 parent 6d94477 commit 65b996b

9 files changed

Lines changed: 683 additions & 534 deletions

assets/theme-v2/css/status.css

Lines changed: 45 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@
3636
}
3737

3838
.toolbox-status-bar {
39+
--toolbox-status-bar-height: var(--space-52);
40+
--toolbox-status-game-max: 220px;
3941
width: 100%;
42+
min-block-size: var(--toolbox-status-bar-height);
4043
border-block: var(--border-standard);
4144
background: var(--panel-overlay-strong);
4245
color: var(--text)
@@ -47,7 +50,7 @@
4750
margin: var(--space-0) auto;
4851
padding: var(--space-10) var(--space-0);
4952
display: grid;
50-
grid-template-columns: minmax(var(--space-0), 1fr) minmax(var(--space-0), 2fr);
53+
grid-template-columns: minmax(var(--space-0), max-content) minmax(var(--space-0), 1fr);
5154
gap: var(--space-16);
5255
align-items: center
5356
}
@@ -56,34 +59,18 @@
5659
min-width: var(--space-0);
5760
display: flex;
5861
align-items: center;
59-
flex-wrap: wrap;
60-
gap: var(--space-14);
62+
justify-content: flex-start;
6163
text-align: left
6264
}
6365

64-
.toolbox-status-bar__field {
65-
min-width: var(--space-0);
66-
display: grid;
67-
gap: var(--space-3)
68-
}
69-
70-
.toolbox-status-bar__label {
71-
color: var(--muted);
72-
font-size: var(--font-size-xs);
73-
font-weight: var(--font-weight-heavy);
74-
letter-spacing: var(--letter-spacing-kicker);
75-
text-transform: uppercase
76-
}
77-
7866
.toolbox-status-bar__game-name {
7967
color: var(--text);
8068
font-size: var(--font-size-base);
81-
overflow-wrap: anywhere
82-
}
83-
84-
.toolbox-status-bar__purpose {
85-
color: var(--muted);
86-
font-size: var(--font-size-sm);
69+
line-height: var(--line-height-tight);
70+
max-width: min(30vw, var(--toolbox-status-game-max));
71+
overflow: hidden;
72+
text-overflow: ellipsis;
73+
white-space: nowrap;
8774
overflow-wrap: anywhere
8875
}
8976

@@ -92,25 +79,17 @@
9279
display: flex;
9380
align-items: center;
9481
justify-content: center;
95-
flex-wrap: wrap;
96-
gap: var(--space-10);
82+
justify-self: center;
9783
text-align: center
9884
}
9985

100-
.toolbox-status-bar__context-type {
101-
flex: 0 0 auto
102-
}
103-
10486
.toolbox-status-bar__message {
10587
margin: var(--space-0);
10688
max-width: var(--measure-lg);
89+
line-height: var(--line-height-copy);
10790
overflow-wrap: anywhere
10891
}
10992

110-
.toolbox-status-bar__action {
111-
flex: 0 0 auto
112-
}
113-
11493
.toolbox-status-bar[data-selected-game-state="active"] {
11594
border-color: color-mix(in srgb, var(--green) 52%, var(--line))
11695
}
@@ -123,22 +102,6 @@
123102
border-color: color-mix(in srgb, var(--red) 52%, var(--line))
124103
}
125104

126-
.toolbox-status-bar[data-toolbox-status-context-kind="error"] .toolbox-status-bar__context-type {
127-
border-color: color-mix(in srgb, var(--red) 62%, var(--line));
128-
color: var(--red)
129-
}
130-
131-
.toolbox-status-bar[data-toolbox-status-context-kind="warning"] .toolbox-status-bar__context-type,
132-
.toolbox-status-bar[data-toolbox-status-context-kind="validation"] .toolbox-status-bar__context-type {
133-
border-color: var(--gold-border-muted);
134-
color: var(--gold)
135-
}
136-
137-
.toolbox-status-bar[data-toolbox-status-context-kind="save"] .toolbox-status-bar__context-type {
138-
border-color: color-mix(in srgb, var(--green) 62%, var(--line));
139-
color: var(--green)
140-
}
141-
142105
body.tool-focus-mode .toolbox-status-bar {
143106
position: fixed;
144107
inset-block-end: var(--space-0);
@@ -148,6 +111,31 @@ body.tool-focus-mode .toolbox-status-bar {
148111
box-shadow: var(--shadow-md)
149112
}
150113

114+
body.tool-focus-mode {
115+
--toolbox-status-bar-height: var(--space-52);
116+
--toolbox-status-top-reserve: var(--space-0)
117+
}
118+
119+
body.tool-focus-mode:has(.platform-banner) {
120+
--toolbox-status-top-reserve: var(--space-52)
121+
}
122+
123+
body.tool-focus-mode .tool-workspace {
124+
height: calc(100vh - var(--toolbox-status-bar-height) - var(--toolbox-status-top-reserve));
125+
max-height: calc(100vh - var(--toolbox-status-bar-height) - var(--toolbox-status-top-reserve))
126+
}
127+
128+
body.tool-focus-mode .tool-column {
129+
height: calc(100vh - var(--toolbox-status-bar-height) - var(--space-20));
130+
max-height: calc(100vh - var(--toolbox-status-bar-height) - var(--space-20))
131+
}
132+
133+
body.tool-focus-mode .tool-center-panel {
134+
box-sizing: border-box;
135+
margin-block-end: var(--toolbox-status-bar-height);
136+
scroll-padding-block-end: var(--toolbox-status-bar-height)
137+
}
138+
151139
.platform-banner {
152140
width: 100%;
153141
border-bottom: var(--border-standard);
@@ -261,12 +249,16 @@ body.tool-focus-mode .toolbox-status-bar {
261249
@media (max-width: 720px) {
262250
.toolbox-status-bar__inner {
263251
width: var(--container-width);
264-
grid-template-columns: 1fr;
252+
grid-template-columns: minmax(var(--space-0), max-content) minmax(var(--space-0), 1fr);
253+
gap: var(--space-10);
265254
text-align: center
266255
}
267256

268-
.toolbox-status-bar__game {
269-
justify-content: center;
270-
text-align: center
257+
.toolbox-status-bar__game-name {
258+
max-width: 34vw
259+
}
260+
261+
.toolbox-status-bar__message {
262+
font-size: var(--font-size-sm)
271263
}
272264
}

assets/theme-v2/js/toolbox-status-bar.js

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -90,37 +90,16 @@ function createStatusBar() {
9090
game.className = "toolbox-status-bar__game";
9191
game.dataset.toolboxSelectedGame = "";
9292

93-
const nameField = document.createElement("div");
94-
nameField.className = "toolbox-status-bar__field";
95-
nameField.dataset.toolboxSelectedGameNameField = "";
96-
const nameLabel = createText("span", "toolbox-status-bar__label", "toolboxSelectedGameNameLabel");
97-
nameLabel.textContent = "Selected Game Name";
9893
const name = createText("strong", "toolbox-status-bar__game-name", "toolboxSelectedGameName");
99-
nameField.append(nameLabel, name);
100-
101-
const purposeField = document.createElement("div");
102-
purposeField.className = "toolbox-status-bar__field";
103-
purposeField.dataset.toolboxSelectedGamePurposeField = "";
104-
const purposeLabel = createText("span", "toolbox-status-bar__label", "toolboxSelectedGamePurposeLabel");
105-
purposeLabel.textContent = "Selected Game Purpose";
106-
const purpose = createText("span", "toolbox-status-bar__purpose", "toolboxSelectedGamePurpose");
107-
purpose.dataset.toolboxSelectedGameMeta = "";
108-
purposeField.append(purposeLabel, purpose);
109-
game.append(nameField, purposeField);
94+
game.append(name);
11095

11196
const center = document.createElement("div");
11297
center.className = "toolbox-status-bar__center";
11398
center.dataset.toolboxStatusCenter = "";
11499

115-
const contextType = createText("span", "pill toolbox-status-bar__context-type", "toolboxStatusContextType");
116100
const message = createText("p", "toolbox-status-bar__message status", "toolboxStatusMessage");
117101
message.setAttribute("role", "status");
118-
const action = document.createElement("a");
119-
action.className = "btn btn--compact toolbox-status-bar__action";
120-
action.dataset.toolboxStatusAction = "";
121-
action.href = mountOptions.gameHubHref;
122-
action.textContent = "Open Game Hub";
123-
center.append(contextType, message, action);
102+
center.append(message);
124103

125104
inner.append(game, center);
126105
bar.append(inner);
@@ -234,33 +213,30 @@ function publishSelectedGameContext(selectedGame, state) {
234213
function classifyToolContext(messageText, state, required) {
235214
const text = String(messageText || "").trim();
236215
if (state === "error") {
237-
return { kind: "error", label: "Error" };
216+
return { kind: "error" };
238217
}
239218
if (required && state === "missing") {
240-
return { kind: "action", label: "Tool Action" };
219+
return { kind: "action" };
241220
}
242221
if (/\b(error|failed|malformed|unavailable|could not)\b/i.test(text)) {
243-
return { kind: "error", label: "Error" };
222+
return { kind: "error" };
244223
}
245224
if (/\b(sign in|refresh|try again|temporarily|blocked)\b/i.test(text)) {
246-
return { kind: "warning", label: "Warning" };
225+
return { kind: "warning" };
247226
}
248227
if (/\b(validation|requirement|requirements|missing|required|open or seed)\b/i.test(text)) {
249-
return { kind: "validation", label: "Validation" };
228+
return { kind: "validation" };
250229
}
251230
if (/\b(saved|created|deleted|updated|loaded|save changes)\b/i.test(text)) {
252-
return { kind: "save", label: "Save State" };
231+
return { kind: "save" };
253232
}
254-
return { kind: "action", label: "Tool Action" };
233+
return { kind: "action" };
255234
}
256235

257236
function renderSelectedGame(bar, selectedGame, state, messageText) {
258237
const required = pageRequiresSelectedGame();
259238
const name = bar.querySelector("[data-toolbox-selected-game-name]");
260-
const purpose = bar.querySelector("[data-toolbox-selected-game-purpose]");
261-
const contextType = bar.querySelector("[data-toolbox-status-context-type]");
262239
const message = bar.querySelector("[data-toolbox-status-message]");
263-
const action = bar.querySelector("[data-toolbox-status-action]");
264240
const nextMessage = messageText || latestToolMessage || (selectedGame
265241
? `Tool context is filtered to ${selectedGame.name}.`
266242
: required
@@ -271,38 +247,27 @@ function renderSelectedGame(bar, selectedGame, state, messageText) {
271247
bar.dataset.selectedGameState = state;
272248
bar.dataset.selectedGameRequired = String(required);
273249
bar.dataset.toolboxStatusContextKind = context.kind;
274-
contextType.textContent = context.label;
275-
action.hidden = false;
276-
action.href = mountOptions.gameHubHref;
277250

278251
if (selectedGame) {
279252
name.textContent = selectedGame.name;
280-
purpose.textContent = selectedGame.purpose || "Game";
281253
message.textContent = nextMessage;
282-
action.textContent = "Open Game Hub";
283254
return;
284255
}
285256

286257
if (!required) {
287258
name.textContent = "No game selected";
288-
purpose.textContent = "Idea Board optional";
289259
message.textContent = nextMessage;
290-
action.textContent = "Open Game Hub";
291260
return;
292261
}
293262

294263
if (state === "error") {
295264
name.textContent = "Unavailable";
296-
purpose.textContent = "Game Hub selected game could not be read";
297265
message.textContent = nextMessage;
298-
action.textContent = "Open Game Hub";
299266
return;
300267
}
301268

302269
name.textContent = "No game selected";
303-
purpose.textContent = "Game Hub owns game selection";
304270
message.textContent = "Select or create a game in Game Hub before using this toolbox page.";
305-
action.textContent = "Select or Create in Game Hub";
306271
}
307272

308273
export function refreshToolboxStatusBar() {

docs_build/dev/BUILD_PR.md

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,48 @@
1-
# PR_26175_ALFA_002-toolbox-status-bar-context-polish
1+
# PR_26175_ALFA_003-toolbox-status-bar-single-row-polish
22

33
## Purpose
4-
Polish the shared toolbox status bar context display so it shows only selected-game name/purpose on the left and categorized tool context in the center.
4+
Update the shared toolbox status bar to a single-row creator context bar.
55

66
## Source Of Truth
7-
This `BUILD_PR.md` is the source of truth for `PR_26175_ALFA_002-toolbox-status-bar-context-polish`.
7+
This `BUILD_PR.md` is the source of truth for `PR_26175_ALFA_003-toolbox-status-bar-single-row-polish`.
88

99
## Exact Scope
10-
- Do not include environment text in the status bar because environment already appears in the platform banner.
11-
- On the left side, display the selected Game Hub game name and selected Game Hub game purpose.
12-
- On the center side, display tool context messages for tool actions, save state, validation messages, warnings, or errors.
10+
- Display only the selected Game Hub game name on the left side.
11+
- Display only the current status message in the center.
12+
- Remove visible status bar labels: `Selected Game Name`, `Selected Game Purpose`, `Save State`, `Tool Action`, `Warning`, and `Error`.
13+
- Remove selected game purpose from the visible status bar.
14+
- Keep the game name and status message on the same row at desktop/toolbox widths.
1315
- Preserve normal placement above the footer.
1416
- Preserve fullscreen/tool display mode bottom anchoring.
17+
- Ensure fullscreen center tool content and its scrollbar stop above the fixed status bar.
18+
- Add bottom reserve equal to the status bar height for the fullscreen center tool area.
1519
- Preserve Idea Board selected-game filtering exclusion.
1620
- Preserve Game Hub as selected-game owner through the existing repository contract.
1721
- Keep the shared Theme V2 toolbox component model.
18-
- Update targeted Playwright coverage for the polished left and center context.
22+
- Keep creator-facing language simple.
23+
- Do not add environment/server details to the UI.
24+
- Update targeted Playwright coverage for the single-row layout and fullscreen bottom reserve.
1925

2026
## Exact Targets
2127
- `docs_build/dev/BUILD_PR.md`
2228
- `assets/theme-v2/js/toolbox-status-bar.js`
2329
- `assets/theme-v2/css/status.css`
2430
- `tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs`
25-
- `docs_build/dev/reports/PR_26175_ALFA_002-toolbox-status-bar-context-polish_report.md`
26-
- `docs_build/dev/reports/PR_26175_ALFA_002-toolbox-status-bar-context-polish_validation-lane.md`
27-
- `docs_build/dev/reports/PR_26175_ALFA_002-toolbox-status-bar-context-polish_requirements-checklist.md`
31+
- `docs_build/dev/reports/PR_26175_ALFA_003-toolbox-status-bar-single-row-polish_report.md`
32+
- `docs_build/dev/reports/PR_26175_ALFA_003-toolbox-status-bar-single-row-polish_validation-lane.md`
33+
- `docs_build/dev/reports/PR_26175_ALFA_003-toolbox-status-bar-single-row-polish_requirements-checklist.md`
2834
- `docs_build/dev/reports/codex_review.diff`
2935
- `docs_build/dev/reports/codex_changed_files.txt`
3036

3137
## Out Of Scope
3238
- No environment status in the toolbox status bar.
33-
- No row highlights.
3439
- No large banners.
35-
- No modal-style status messages.
36-
- No inline styles, style blocks, or page-local CSS.
40+
- No modal messages or modal-style status messages.
41+
- No row highlights.
42+
- No selected game purpose in the visible status bar.
43+
- No visible status category labels in the status bar.
3744
- No API/service contract changes.
45+
- No inline styles, style blocks, or page-local CSS.
3846
- No engine core changes.
3947
- No `start_of_day` folder changes.
4048

@@ -55,5 +63,5 @@ rg -n "<style|style=" assets/theme-v2/js/toolbox-status-bar.js assets/theme-v2/c
5563
Create repo-structured delta ZIP:
5664

5765
```text
58-
tmp/PR_26175_ALFA_002-toolbox-status-bar-context-polish_delta.zip
66+
tmp/PR_26175_ALFA_003-toolbox-status-bar-single-row-polish_delta.zip
5967
```
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# PR_26175_ALFA_003-toolbox-status-bar-single-row-polish Report
2+
3+
## Summary
4+
Updated the shared toolbox status bar to a single-row creator context bar.
5+
6+
## Changes
7+
- Removed visible selected-game labels, selected-game purpose, status category pills, and status action links from the status bar.
8+
- Kept the visible status bar contract to selected game name on the left and current status message in the center.
9+
- Preserved Game Hub ownership of selected-game context and Idea Board selected-game filtering exclusion.
10+
- Preserved normal placement above the footer.
11+
- Preserved fullscreen bottom anchoring and reserved the status-bar height for the fullscreen center tool area.
12+
- Updated targeted Playwright coverage for removed labels, visible game/message text, same-row layout, and fullscreen center-panel bounds.
13+
14+
## Contract Notes
15+
- No API/service contract changes were made.
16+
- No browser-owned product data is used as selected-game source of truth.
17+
- Environment/server details remain outside the status bar.
18+
- Theme V2 shared CSS/classes remain the styling surface.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# PR_26175_ALFA_003-toolbox-status-bar-single-row-polish Requirements Checklist
2+
3+
- PASS: Status bar displays only selected game name and status message.
4+
- PASS: Selected game name is left anchored.
5+
- PASS: Status message is center anchored.
6+
- PASS: Visible labels were removed.
7+
- PASS: Selected game purpose was removed from the visible status bar.
8+
- PASS: Game name and status message are on the same row.
9+
- PASS: Fullscreen status bar remains fixed at the bottom.
10+
- PASS: Fullscreen center panel stops above the status bar.
11+
- PASS: Fullscreen center panel has bottom reserve equal to the status bar height.
12+
- PASS: Normal placement above the footer is preserved.
13+
- PASS: Idea Board exclusion is preserved.
14+
- PASS: Game Hub remains selected-game owner.
15+
- PASS: No large banners or modal messages were added.
16+
- PASS: No inline styles, style blocks, or page-local CSS were added.
17+
- PASS: Theme V2 shared CSS/classes are used.
18+
- PASS: Targeted Playwright coverage was updated and passed.

0 commit comments

Comments
 (0)