library: centre the quarter-turn pair on the stage bar

The bar under the picture is the grid it needs to be: equal free tracks either
side of the two buttons land them on the picture's own centre whatever OPEN and
the stars measure, and the pair keeps the ends it does not own. Under 700px the
stage is too narrow for one line, so the bar wraps as it did and the lines it
wraps to are centred.
This commit is contained in:
2026-10-06 18:22:40 +07:00
parent 0df62b6248
commit 66b159b3bd
2 changed files with 27 additions and 6 deletions
+8 -6
View File
@@ -1635,34 +1635,36 @@ export function Library() {
angle — the next visit, the next scan and the studio angle — the next visit, the next scan and the studio
all read it off the row, so it is never turned all read it off the row, so it is never turned
twice. Two buttons and not a dial: a quarter is the twice. Two buttons and not a dial: a quarter is the
only turn a photo is ever out by. */} only turn a photo is ever out by. They sit on the
centre of the bar, over the middle of the picture
above them, because they are what the eye comes down
to after it; the score stays out at the edge. */}
<button <button
type="button" type="button"
className="chip lib-icon" className="chip lib-icon lib-turn"
data-key="lib-turn-left" data-key="lib-turn-left"
aria-label={t('lib.rotateLeft')} aria-label={t('lib.rotateLeft')}
title={t('lib.rotateLeft')} title={t('lib.rotateLeft')}
onClick={() => void turn(frame, -1)} onClick={() => void turn(frame, -1)}
> >
<svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth="1.4"> <svg viewBox="0 0 16 16" width="24" height="24" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth="1.3">
<path d="M3.2 6.2A5.2 5.2 0 1 1 3.5 10" /> <path d="M3.2 6.2A5.2 5.2 0 1 1 3.5 10" />
<path d="M1.6 3.1v3.4h3.4" /> <path d="M1.6 3.1v3.4h3.4" />
</svg> </svg>
</button> </button>
<button <button
type="button" type="button"
className="chip lib-icon" className="chip lib-icon lib-turn"
data-key="lib-turn-right" data-key="lib-turn-right"
aria-label={t('lib.rotateRight')} aria-label={t('lib.rotateRight')}
title={t('lib.rotateRight')} title={t('lib.rotateRight')}
onClick={() => void turn(frame, 1)} onClick={() => void turn(frame, 1)}
> >
<svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth="1.4"> <svg viewBox="0 0 16 16" width="24" height="24" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth="1.3">
<path d="M12.8 6.2A5.2 5.2 0 1 0 12.5 10" /> <path d="M12.8 6.2A5.2 5.2 0 1 0 12.5 10" />
<path d="M14.4 3.1v3.4h-3.4" /> <path d="M14.4 3.1v3.4h-3.4" />
</svg> </svg>
</button> </button>
<span className="adm-spacer" />
{/* The frame's own score, and the only place one is {/* The frame's own score, and the only place one is
given: the star that is lit is the score it has, given: the star that is lit is the score it has,
and the star under the click is the score it gets — and the star under the click is the score it gets —
+19
View File
@@ -1180,6 +1180,21 @@ button.hint:disabled { cursor: default; }
.lib-root .adm-stage > .lib-noimg { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; } .lib-root .adm-stage > .lib-noimg { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; }
.lib-root .adm-stage > .adm-meta, .lib-root .adm-stage > .adm-meta,
.lib-root .adm-stage > .chip-row { flex: 0 0 auto; } .lib-root .adm-stage > .chip-row { flex: 0 0 auto; }
/* The bar under the stage is four tracks — a free one to either side of the two
quarter-turns, so the pair lands on the picture's own centre whatever the
OPEN button and the stars happen to measure, and they stay at the ends they
belong to. Equal `1fr` either side is what does it; a spacer could not, since
the two end blocks are not the same width. */
.lib-root .adm-stage > .chip-row { display: grid; grid-template-columns: 1fr auto auto 1fr; align-items: center; }
.lib-root .adm-stage > .chip-row > .btn { justify-self: start; }
.lib-root .adm-stage > .chip-row > .lib-stars { justify-self: end; }
/* Under ~700px of window the stage is narrower than those four need on one line,
and a grid would run the stars off the edge of it rather than wrap. It goes
back to the flex row it was — the lines it wraps to are centred under the
picture, so nothing slides off and the pair still sits in the middle. */
@media (max-width: 700px) {
.lib-root .adm-stage > .chip-row { display: flex; justify-content: center; }
}
/* All thumbs: the wall scrolls down inside the stage, and its own scrollbar on /* All thumbs: the wall scrolls down inside the stage, and its own scrollbar on
the right edge is what reaches the frames below. */ the right edge is what reaches the frames below. */
.lib-root .adm-grid { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 6px; } .lib-root .adm-grid { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 6px; }
@@ -1212,6 +1227,10 @@ button.hint:disabled { cursor: default; }
/* The views are a glyph each (a frame, a wall of thumbs), so the row stays a row /* The views are a glyph each (a frame, a wall of thumbs), so the row stays a row
when the window is narrow. */ when the window is narrow. */
.lib-icon { padding: 5px 8px; justify-content: center; } .lib-icon { padding: 5px 8px; justify-content: center; }
/* The two quarter-turn buttons under the stage: a bigger glyph than a view icon,
so the padding grows with it — the target is what the thumb aims at, and these
are pressed far more often than a view is switched. */
.chip.lib-turn { padding: 7px 12px; }
/* A folder's own menu, on a right click. Fixed, so the tree's own scroll cannot /* A folder's own menu, on a right click. Fixed, so the tree's own scroll cannot
clip it; the position is clamped to the window when it is drawn. clip it; the position is clamped to the window when it is drawn.
Sized after a catalogue's own menu rather than after a page's: it hangs off a Sized after a catalogue's own menu rather than after a page's: it hangs off a