Files
olivv-cs-ComfyUI-FunPack/app/ui/composer/elements/input.css
T
digital-garbageandClaude Sonnet 5.5 aa31b95ea5 Timeline header on one line; kit literals into tokens; Composer fits; running-state viewport test; remove Auto Montage
- 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>
2026-11-06 14:28:45 +02:00

112 lines
6.7 KiB
CSS

.cx-input, .cx-textarea, .cx-select {
width: 100%;
border: var(--bw) solid var(--line); border-radius: var(--ctl-r);
background: var(--elev-2); color: var(--text);
font-family: var(--font-ui);
transition: border-color var(--dur-1) var(--ease-standard);
}
.cx-input-md { height: var(--ctl-h-lg); padding: 0 var(--ctl-pad-x-md); font-size: var(--fs-4); }
.cx-input-sm { height: var(--ctl-h-md); padding: 0 var(--ctl-pad-x-sm); font-size: var(--fs-5); }
.cx-input:hover:not(:disabled), .cx-textarea:hover:not(:disabled) { border-color: var(--line-hover); }
.cx-input:disabled, .cx-textarea:disabled, .cx-select:disabled { opacity: var(--disabled-opacity); }
.cx-input::placeholder, .cx-textarea::placeholder { color: var(--faint); }
.cx-number { font-variant-numeric: tabular-nums; }
.cx-number-wrap { display: inline-flex; align-items: center; gap: var(--sp-2); width: 100%; }
.cx-unit { font-size: var(--fs-6); color: var(--muted); }
.cx-stepper { display: inline-flex; align-items: stretch; gap: var(--sp-1); }
.cx-stepper .cx-number { text-align: center; }
.cx-step-btn {
width: var(--ctl-h-lg); height: var(--ctl-h-lg); flex: none;
border: var(--bw) solid var(--line); border-radius: var(--ctl-r);
background: var(--elev-2); color: var(--muted);
font-size: var(--fs-4); line-height: 1; cursor: pointer;
}
.cx-step-btn:hover { border-color: var(--line-hover); color: var(--text); }
.cx-textarea {
padding: var(--sp-3) var(--ctl-pad-x-md);
font-size: var(--fs-4); line-height: var(--lh-snug);
resize: vertical; min-height: var(--ctl-h-xl);
}
/* In a window the box shares the room with its tabs, hint and folds: it gives way as the screen gets shorter, so the window does not scroll inside itself. */
.cx-window .cx-textarea { max-block-size: min(28dvh, var(--window-field-max-h)); }
.cx-autogrow { resize: none; overflow: hidden; }
.cx-fold { min-height: var(--ctl-h-md); height: var(--ctl-h-md); padding: var(--sp-2) var(--ctl-pad-x-sm); font-size: var(--fs-5); }
.cx-fold:not(:focus) { padding-block: 0; line-height: calc(var(--ctl-h-md) - var(--bw-2)); } /* folded: the first line centred, the rest fully out of sight */
.cx-search { appearance: none; }
.cx-search::-webkit-search-cancel-button { filter: grayscale(1) opacity(.6); }
.cx-filter { display: flex; flex-direction: column; gap: var(--sp-3); min-width: var(--field-min-w); }
/* filterList always builds its own search box, which is right everywhere it
is the ONLY way to narrow the list -- and wrong stacked under a search box
that already re-queries the server on every keystroke: two boxes doing the
same job, one of them silently filtering an already-server-filtered
subset, with no way to tell which one produced what is on screen. The
node-add picker (pipeline_window.js) is the one place that already has an
outer search; this hides filterList's own for exactly that container. */
.cx-node-picker-results .cx-filter > .cx-search { display: none; }
.cx-filter-list {
display: flex; flex-direction: column; gap: 1px;
max-height: var(--textarea-max-h); overflow-y: auto; overflow-x: hidden;
border: var(--bw) solid var(--line); border-radius: var(--r-3);
background: var(--elev-1); padding: var(--sp-1);
}
.cx-filter-row {
display: flex; align-items: center; gap: var(--sp-3);
padding: var(--sp-4) var(--sp-5); border: 0; border-radius: var(--r-2);
background: transparent; color: var(--text);
font-size: var(--fs-5); text-align: left; cursor: pointer; width: 100%;
}
.cx-filter-gap { block-size: var(--sp-5); }
.cx-filter-row:hover { background: var(--hover); }
.cx-filter-row.cx-on { background: var(--accent-soft); color: var(--accent-text); }
.cx-filter-row.cx-on .cx-filter-label { font-weight: var(--fw-semibold); }
/* A column so a wrapping hint sits directly under its own label, both flush
to the same left edge, instead of floating as a baseline-aligned sibling
of the icon and the label. Centred on the icon: with the hint gone (a
nav row now, not a compact picker's two-line entry) top-aligning the two
just looks like a mistake. */
.cx-filter-text { display: flex; flex-direction: column; gap: var(--sp-1); flex: 1; min-width: 0; justify-content: center; }
.cx-filter-label { display: block; }
.cx-filter-hint { display: block; font-size: var(--fs-7); color: var(--muted); line-height: var(--lh-snug); }
.cx-filter-empty { padding: var(--sp-5); font-size: var(--fs-6); color: var(--faint); text-align: center; }
/* A chip, not a bare glyph floating in the row -- the thing a nav list reads
as unfinished without. `tone` is a closed set of pre-approved looks
(accent/danger/warn/good/neutral), the same rule as everywhere else in the
kit; there is no path from item data to a raw colour. */
.cx-filter-icon {
display: inline-flex; align-items: center; justify-content: center;
width: var(--ctl-h-chip); height: var(--ctl-h-chip); flex: 0 0 auto; border-radius: var(--r-2);
background: var(--elev-3); color: var(--text); font-size: var(--fs-6); line-height: 1;
/* Optical, against the label's cap-height, not the row's own top edge. */
margin-block-start: 1px;
}
.cx-filter-icon-accent { background: var(--grad-accent); color: var(--on-accent); }
.cx-filter-icon-danger { background: linear-gradient(180deg, var(--danger), color-mix(in srgb, var(--danger) 82%, black)); color: var(--on-status); }
.cx-filter-icon-warn { background: linear-gradient(180deg, var(--warn), color-mix(in srgb, var(--warn) 82%, black)); color: var(--on-status); }
.cx-filter-icon-good { background: linear-gradient(180deg, var(--good), color-mix(in srgb, var(--good) 82%, black)); color: var(--on-status); }
.cx-filter-icon-neutral { background: linear-gradient(180deg, var(--muted), color-mix(in srgb, var(--muted) 82%, black)); color: var(--elev-0); }
.cx-filter-row.cx-on .cx-filter-icon { box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-hi) 50%, transparent); }
/* The Settings sidebar and window body: see settings.css. */
/* Used as a whole pane (the Settings sidebar) rather than a compact dropdown
list -- the 240px cap and boxed border/background are right for the small
version and wrong for this one, so a host opts in with this class instead
of the base rules changing under every other consumer. */
.cx-filter-full { min-block-size: 0; block-size: 100%; }
.cx-filter-full .cx-filter-list {
max-height: none; flex: 1 1 auto; min-block-size: 0;
border: 0; background: transparent; padding: 0;
}
.cx-filter-full .cx-filter-row { padding: var(--sp-3) var(--sp-3); }
/* Selected is never colour alone (Apple HIG, Color): a picker row also carries a
check mark, and the label is bolder. Navigation lists (the full-pane variant)
keep the highlight only, as a sidebar does. */
.cx-filter-row.cx-on:not(.cx-filter-full *)::after { content: "✓"; margin-inline-start: auto; font-weight: var(--fw-bold); }