Top-right action strip: pin undo/redo + canvas-size readouts under Nostr widget

The undo/redo pair and the trim/sheet canvas-size pills lived inside
.topbar's flex row, which wraps at narrow widths. Adam wanted them in a
permanent, predictable place so muscle memory works regardless of
editor mode or sidebar state.

Changes:
  - .status is now `position: fixed; top: var(--top-strip-height);
    right: 0; flex-wrap: nowrap` with the same panel/border styling as
    the Nostr widget — a second strip directly below it.
  - Reordered the markup so the canvas-size pills come first and the
    undo/redo group last, so undo/redo end up hugging the viewport edge
    and the pills sit to their left (matching the requested layout).
  - Dropped the `body.app-designer .status` override (full-width
    left-aligned), since the new positioning is universal across modes.
  - updateNostrWidgetSpace() now measures the wider of the Nostr widget
    or the new strip and reserves topbar right padding accordingly, so
    the project title can't slide under the strip.

Verified via CDP at 1440px (cover, customart, pixelart modes) and at
900px narrow — strip stays pinned top-right with undo/redo on the
outside edge in every case.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.7 committed 2026-05-28 08:59:40 -04:00
1 parent 3c40951a8a
commit 733d123edc
2 files changed
+44 -13

No files matched your search

+15 -2
View File
@@ -5,8 +5,12 @@ Running list of deferred work. Detailed specs for the larger items live in
## Adam's working list
_(Empty — see "Shipped (recent)" below for the items that just
landed. Drop new items in here as they come up.)_
- **Pixel canvas size dropdown — fix sidebar clipping.** When the
sidebar is open and the canvas size row wraps to a second line on
the left, the pixel-art canvas-size dropdown is clipped by the
sidebar. Easiest fix is probably "always right-align when wrapped"
so the dropdown opens away from the sidebar; or move the dropdown
to a placement that can't collide with the sidebar.
## QR code layer — remaining phases
@@ -84,6 +88,15 @@ Each has a full spec in `docs/`.
## Shipped (recent)
- **Top-right action strip — permanent, never wraps.** Pulled the
canvas-size readouts and the undo / redo pair out of the topbar's
flex flow and pinned them in a fixed strip directly under the Nostr
widget, right-anchored, with `flex-wrap: nowrap`. Order: canvas-size
pills on the left, undo / redo on the right (so undo / redo hug the
viewport edge). The topbar's right padding now tracks the wider of
the Nostr widget or the strip via the existing
`--nostr-widget-space` var, so the project title never slides under
it.
- **Click canvas background → deselect.** The existing #sheet click
handler missed clicks in the gutter between sheet edge and
previewShell edge; added a #previewShell handler.
+29 -11
View File
@@ -992,20 +992,30 @@
padding: 22px var(--nostr-widget-space, 210px) 14px 26px;
}
/* Permanent top-right action strip — pinned directly under the Nostr
widget so the undo/redo controls and the canvas-size readouts always
live in the same place regardless of editor mode, sidebar state, or
window width. Never wraps. */
.status {
position: fixed;
top: var(--top-strip-height, 34px);
right: 0;
z-index: 90;
display: flex;
flex-wrap: nowrap;
gap: 10px;
gap: 8px;
align-items: center;
color: var(--muted);
font-size: .86rem;
min-width: 0;
background: var(--panel);
border-left: 1px solid var(--line);
border-bottom: 1px solid var(--line);
padding: 4px 10px 4px 14px;
box-sizing: border-box;
}
body.app-designer .status {
flex-basis: 100%;
justify-content: flex-start;
}
body.dark .status { color: var(--muted); }
@media print { .status { display: none !important; } }
.pill {
border: 1px solid var(--line);
@@ -3517,12 +3527,12 @@
<p class="subhead printHelp">Left-to-right layout is back cover, spine, front cover.</p>
</div>
<div class="status">
<span class="pill" id="trimReadout"></span>
<span class="pill" id="sheetReadout"></span>
<div class="undoRedoGroup">
<button type="button" id="undoBtn" class="undoRedoBtn" disabled aria-label="Undo">↶</button>
<button type="button" id="redoBtn" class="undoRedoBtn" disabled aria-label="Redo">↷</button>
</div>
<span class="pill" id="trimReadout"></span>
<span class="pill" id="sheetReadout"></span>
</div>
</div>
@@ -18350,10 +18360,16 @@
}
function updateNostrWidgetSpace() {
// Reserve right-edge padding on the topbar for whichever fixed strip
// is wider: the Nostr widget itself, or the action strip below it
// (canvas-size pills + undo/redo). Without this, a narrow topbar
// would let the project title slide under the action strip.
const widget = $('nostrWidget');
if (!widget) return;
const rect = widget.getBoundingClientRect();
const space = Math.ceil(rect.width || 0) + 18;
const statusStrip = document.querySelector('.topbar > .status');
let widest = 0;
if (widget) widest = Math.max(widest, widget.getBoundingClientRect().width || 0);
if (statusStrip) widest = Math.max(widest, statusStrip.getBoundingClientRect().width || 0);
const space = Math.ceil(widest) + 18;
document.documentElement.style.setProperty('--nostr-widget-space', `${space}px`);
}
@@ -18364,6 +18380,8 @@
if (typeof ResizeObserver === 'function') {
const observer = new ResizeObserver(updateNostrWidgetSpace);
observer.observe(widget);
const statusStrip = document.querySelector('.topbar > .status');
if (statusStrip) observer.observe(statusStrip);
}
window.addEventListener('resize', updateNostrWidgetSpace);
}