- 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>
89 lines
4.8 KiB
CSS
89 lines
4.8 KiB
CSS
.cx-btn {
|
|
display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
|
|
border: var(--bw) solid var(--line); border-radius: var(--ctl-r);
|
|
background: var(--grad-raise); color: var(--text);
|
|
font-family: var(--font-ui); font-weight: var(--fw-medium);
|
|
white-space: nowrap; cursor: pointer;
|
|
transition: background var(--dur-1) var(--ease-standard),
|
|
border-color var(--dur-1) var(--ease-standard),
|
|
color var(--dur-1) var(--ease-standard);
|
|
}
|
|
.cx-btn-xl { height: var(--ctl-h-xl); padding: 0 var(--ctl-pad-x-xl); font-size: var(--fs-4); }
|
|
.cx-btn-lg { height: var(--ctl-h-lg); padding: 0 var(--ctl-pad-x-lg); font-size: var(--fs-5); }
|
|
.cx-btn-md { height: var(--ctl-h-md); padding: 0 var(--ctl-pad-x-md); font-size: var(--fs-5); }
|
|
.cx-btn-menu { height: var(--ctl-h-menu); padding: 0 var(--sp-4); font-size: var(--fs-5); }
|
|
.cx-btn-sm { height: var(--ctl-h-sm); padding: 0 var(--ctl-pad-x-sm); font-size: var(--fs-6); }
|
|
|
|
.cx-btn:hover:not(:disabled) { border-color: var(--line-hover); background: var(--hover); }
|
|
.cx-btn:active:not(:disabled) { border-color: var(--line-active); }
|
|
.cx-btn:disabled { opacity: var(--disabled-opacity); cursor: default; }
|
|
|
|
.cx-btn-primary {
|
|
background: var(--grad-accent); border-color: var(--accent);
|
|
color: var(--on-accent); font-weight: var(--fw-bold);
|
|
box-shadow: var(--glow-accent);
|
|
}
|
|
/* The SURFACE brightens, not the button.
|
|
`filter: brightness()` applies to the whole element, text included -- so the
|
|
label was lightened along with the fill under it and the one thing that had
|
|
to stay readable lost contrast in both themes. The label's colour is fixed
|
|
and only the fill moves, one step up the same accent ramp. */
|
|
.cx-btn-primary:hover:not(:disabled) {
|
|
background: var(--grad-accent-hover); border-color: var(--accent-hover-edge);
|
|
}
|
|
.cx-btn-primary:active:not(:disabled) { background: var(--accent-lo); }
|
|
|
|
.cx-btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, var(--line)); }
|
|
.cx-btn-danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 12%, transparent); border-color: var(--danger); }
|
|
|
|
.cx-btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
|
|
.cx-btn-ghost:hover:not(:disabled) { background: var(--hover); color: var(--text); }
|
|
|
|
.cx-btn-icon { line-height: 1; }
|
|
.cx-btn-label:empty { display: none; }
|
|
|
|
.cx-icon-btn {
|
|
display: inline-flex; align-items: center; justify-content: center;
|
|
border: var(--bw) solid transparent; border-radius: var(--r-2);
|
|
background: transparent; color: var(--muted); cursor: pointer; padding: 0;
|
|
transition: background var(--dur-1) var(--ease-standard), color var(--dur-1) var(--ease-standard);
|
|
}
|
|
.cx-icon-btn-md { width: var(--ctl-h-md); height: var(--ctl-h-md); font-size: var(--fs-4); }
|
|
.cx-icon-btn-sm { width: var(--ctl-h-icon); height: var(--ctl-h-icon); font-size: var(--fs-6); }
|
|
.cx-icon-btn-micro { width: var(--ctl-h-icon-sm); height: var(--ctl-h-icon-sm); font-size: var(--fs-7); }
|
|
.cx-icon-btn:hover:not(:disabled) { background: var(--hover); color: var(--text); }
|
|
.cx-icon-btn[aria-pressed="true"] { color: var(--accent); background: var(--accent-soft); }
|
|
.cx-icon-btn:disabled { opacity: var(--disabled-opacity); cursor: default; }
|
|
|
|
.cx-btn-group { display: inline-flex; }
|
|
.cx-btn-group .cx-btn { border-radius: 0; margin-left: calc(var(--bw) * -1); }
|
|
.cx-btn-group .cx-btn:first-child { border-radius: var(--ctl-r) 0 0 var(--ctl-r); margin-left: 0; }
|
|
.cx-btn-group .cx-btn:last-child { border-radius: 0 var(--ctl-r) var(--ctl-r) 0; }
|
|
.cx-btn-group .cx-btn:only-child { border-radius: var(--ctl-r); }
|
|
/* A pressed toggle, grouped or not. Scoping this to .cx-btn-group meant a
|
|
standalone toggle -- the region buttons in the timeline bar -- carried
|
|
aria-pressed and looked identical either way: a control that reports its state
|
|
to a screen reader and not to the eye. */
|
|
.cx-btn.cx-on {
|
|
background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text);
|
|
}
|
|
.cx-btn-group .cx-btn.cx-on {
|
|
position: relative; z-index: 1; /* its border wins over its neighbours' */
|
|
}
|
|
|
|
.cx-btn-spin {
|
|
width: var(--ctl-icon-xs); height: var(--ctl-icon-xs); border-radius: var(--r-pill);
|
|
border: var(--bw-2) solid color-mix(in srgb, currentColor 30%, transparent);
|
|
border-top-color: currentColor;
|
|
animation: cx-spin 800ms linear infinite;
|
|
}
|
|
@keyframes cx-spin { to { transform: rotate(360deg); } }
|
|
/* Render: the teal one, as v4 had it -- the output side of Generate. */
|
|
.cx-btn-render {
|
|
background: linear-gradient(var(--teal), color-mix(in srgb, var(--teal) 78%, black));
|
|
color: var(--on-teal); border-color: var(--teal); font-weight: var(--fw-semibold);
|
|
}
|
|
.cx-btn-render:hover:not(:disabled) { filter: brightness(1.08); }
|
|
|
|
.cx-btn.cx-on, .cx-rail-item.cx-on { font-weight: var(--fw-semibold); }
|