- Header: view toggles (Assets/Preview/Properties/Auto-hide) move to the top bar; progress, the prompt warning and scene actions (rate, upscale, interpolate) move to the row under the toolbar; the timeline head never wraps from 1000px up and never clips its controls. The top bar grows a line instead of spilling when it wraps. - Kit: every literal pixel size in element CSS is a token (the ratchet test is now zero); Composer's text box follows the viewport; the catalogue shows the component sizes. - test:viewport adds a fake ComfyUI queue and socket for the render-running state and asserts the header is one row. - Auto Montage removed (button, window, code, README/docs, tests). Saved projects holding pieces it made still load: the reused flag is kept. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
70 lines
5.5 KiB
CSS
70 lines
5.5 KiB
CSS
/* The frame's proportions, as v4 had them: fixed side columns and a fixed-height timeline across the bottom. */
|
|
:root { --media-w: clamp(180px, 20vw, 280px); --properties-w: clamp(270px, 28vw, 360px); --timeline-h: clamp(340px, 42vh, 380px); --pad: 10px; --pgap: 10px; }
|
|
.fp-main { flex-direction: column; padding: 0 var(--pad) var(--pad); gap: var(--pgap); }
|
|
/* Narrower windows wrap the timeline's header and toolbar onto more rows, so its fixed height gets more room for the lanes. */
|
|
@media (max-width: 1250px) { :root { --timeline-h: clamp(380px, 44vh, 440px); } }
|
|
.fp-row { flex: 1 1 auto; flex-direction: row; min-block-size: 0; gap: var(--pgap); }
|
|
.fp-row > *, .fp-main > :nth-child(2) { min-inline-size: 0; border: var(--bw) solid var(--line); border-radius: var(--card-r); overflow: hidden; background: var(--elev-1); }
|
|
.fp-row > :first-child { flex: 0 0 var(--media-w); }
|
|
.fp-row > :nth-child(2) { flex: 1 1 auto; }
|
|
.fp-row > :nth-child(3) { flex: 0 0 var(--properties-w); }
|
|
.fp-main > :nth-child(2) { flex: 0 0 var(--timeline-h); min-block-size: 200px; }
|
|
.cx-frame-head { padding-inline: calc(var(--sp-6) + var(--sp-1)); }
|
|
.cx-frame-head > .cx-toolbar { gap: calc(var(--sp-6) + var(--sp-3)); }
|
|
/* A zone body is a scroller of rows: they keep their height instead of squashing, and a tab strip spans the zone. */
|
|
.cx-zone .cx-panel-body > :not(.cx-stack-fill):not(.cx-viewer) { flex-shrink: 0; }
|
|
.cx-zone .cx-stack-fill > :not(.cx-viewer):not(.cx-stack-fill) { flex-shrink: 0; }
|
|
.cx-zone .cx-stack-fill > .cx-segmented { display: flex; }
|
|
.cx-zone .cx-stack-fill > .cx-segmented .cx-segment { flex: 1 1 auto; }
|
|
[hidden] { display: none !important; }
|
|
/* An empty zone says so in the middle of it, with the controls kept at its foot. */
|
|
.cx-zone .cx-stack-fill > .cx-empty { flex: 1 1 auto; justify-content: center; }
|
|
|
|
/* Splitters: thin hit areas straddling the zone borders. */
|
|
.fp-main, .fp-row { position: relative; } /* side bars live in the row, so they stop above the timeline */
|
|
.fp-split { position: absolute; z-index: 20; background: transparent; touch-action: none; }
|
|
.fp-split:hover { background: var(--accent, var(--line)); opacity: .5; }
|
|
.fp-split-left, .fp-split-right { top: 0; bottom: 0; inline-size: 7px; cursor: col-resize; }
|
|
.fp-split-left { left: calc(var(--media-w) + var(--pgap) / 2 - 3.5px); }
|
|
.fp-split-right { right: calc(var(--properties-w) + var(--pgap) / 2 - 3.5px); }
|
|
.fp-split-bottom { left: 0; right: 0; block-size: 7px; bottom: calc(var(--pad) + var(--timeline-h) + var(--pgap) / 2 - 3.5px); cursor: row-resize; }
|
|
|
|
/* Dock: a hidden zone leaves the row (and the splitter beside it). */
|
|
.fp-hide-assets .fp-row > :nth-child(1),
|
|
.fp-hide-preview .fp-row > :nth-child(2),
|
|
.fp-hide-properties .fp-row > :nth-child(3) { display: none; }
|
|
.fp-hide-assets .fp-split-left, .fp-hide-properties .fp-split-right, .fp-hide-preview .fp-split-right { display: none; }
|
|
.fp-hide-preview .fp-row > :nth-child(3), .fp-hide-preview.fp-hide-properties .fp-row > :nth-child(1) { flex: 1 1 auto; }
|
|
.fp-hide-assets.fp-hide-preview .fp-row > :nth-child(3) { flex: 1 1 auto; }
|
|
.fp-split { border: 0 !important; }
|
|
|
|
/* Auto-hide timeline: its title bar and a strip; full height once the pointer rests on the strip or the timeline, or during a drag. */
|
|
:root.fp-peek .fp-main { position: relative; padding-block-end: calc(var(--peek-h, 64px) + var(--pgap)); }
|
|
:root.fp-peek .fp-main > :nth-child(2) { position: absolute; inset-inline: 0; bottom: 0; block-size: auto; min-block-size: 0; z-index: 20; overflow: hidden; }
|
|
:root.fp-peek .fp-main > :nth-child(2) .cx-panel-body { display: none; }
|
|
:root.fp-peek.fp-peek-open .fp-main > :nth-child(2) { block-size: var(--timeline-h); overflow: visible; }
|
|
:root.fp-peek.fp-peek-open .fp-main > :nth-child(2) .cx-panel-body { display: block; }
|
|
.fp-peek-strip { display: none; }
|
|
:root.fp-peek .fp-peek-strip { display: flex; align-items: center; justify-content: center; block-size: 26px; flex: none; font-size: var(--fs-6); color: var(--faint); user-select: none; }
|
|
:root.fp-peek .fp-peek-strip:hover { color: var(--text); }
|
|
:root.fp-peek.fp-peek-open .fp-peek-strip { display: none; }
|
|
:root.fp-peek .fp-split-bottom { display: none; }
|
|
|
|
/* The timeline's header is ONE line wherever its controls can physically fit (about 1000px and up). It never spreads
|
|
its controls apart: the room goes to the text that can give way (hints, the step counter), which truncates, and
|
|
below the widest layouts a button that has an icon shows only the icon (its label stays for screen readers). */
|
|
@media (min-width: 1000px) {
|
|
.fp-main > :nth-child(2) > .cx-panel-head { flex-wrap: nowrap; column-gap: var(--sp-3); }
|
|
.fp-main > :nth-child(2) > .cx-panel-head .cx-panel-actions { flex: 1 1 0; flex-wrap: nowrap; min-inline-size: 0; overflow: hidden; }
|
|
.fp-main > :nth-child(2) > .cx-panel-head .cx-panel-status { flex: none; flex-wrap: nowrap; gap: var(--sp-2); }
|
|
.fp-main > :nth-child(2) > .cx-panel-head .cx-toolbar { flex-wrap: nowrap; min-inline-size: 0; }
|
|
.fp-main > :nth-child(2) > .cx-panel-head .cx-panel-actions > .cx-toolbar { flex: 0 1 auto; }
|
|
.fp-main > :nth-child(2) > .cx-panel-head .cx-btn, .fp-main > :nth-child(2) > .cx-panel-head .cx-chip { flex: none; }
|
|
.fp-main > :nth-child(2) > .cx-panel-head :is(.cx-hint, .cx-t) { flex: 0 1 auto; min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
}
|
|
@media (min-width: 1000px) and (max-width: 1500px) {
|
|
.fp-main > :nth-child(2) > .cx-panel-head .cx-btn:has(.cx-btn-icon) .cx-btn-label {
|
|
position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
|
|
}
|
|
}
|