v4's arrangement, which is the one that reads as an editor: a zone head holds what acts on THAT zone, so the app grows a bar of its own for what acts on the app. * The menu bar. Brand, View and Settings, and whether ComfyUI is still on the other end. Only menus with something real in them exist -- an empty File menu is a promise the app does not keep. * The prompt is written in the CONSTRUCTOR, a window. v4 called this the Composer; that name is taken here by the element kit, and two things called Composer in one repo is one thing nobody can search for. It is the longest thing a person writes and the least often read, and a permanent third of the centre column is the room the timeline needs. The host is built at startup and outlives every opening, so a window that opens twice does not throw away what was typed. * The timeline replaces it, and Generate moves into its head with what the run is doing at the far end of the same head. No bar across the bottom: one that spans the window belongs to no region. Four faults found on the way, three of them mine and one much older: * THE OVERLAY ROOT WAS A STACKING CONTEXT. It documents at length that it must never be one -- and then set `position: fixed`, which makes one on its own. So the whole z ladder was measured inside that single element: an open menu at z 500 painted UNDER a button at z 1. Every overlay in the app was one positive z-index away from being buried, and the only reason nobody had seen it is that almost nothing claims a z-index. The root is static and zero-sized now; every layer in it is fixed already. * Generate's hover ran `filter: brightness()`, which lightens the LABEL along with the fill under it -- the one thing that had to stay readable lost contrast in both themes. Only the fill moves now, and which way it moves depends on the theme: dark's accent carries near-black text so it goes lighter, light's carries white so it goes darker. Measured: no gradient stop under 4.1:1, hovered or at rest. * A fixed-height head could not shrink below the width of everything in it, and a head now holds a title, three controls and a status. That min-content became the centre column's, so a 768px window laid out 878px wide and scrolled sideways. It wraps now, as v4's does. * A CSS patch of mine silently did nothing because its anchor text had moved and I had left the assertion off that one replacement. Every patch asserts now.
74 lines
4.0 KiB
CSS
74 lines
4.0 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-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); }
|
|
.cx-btn-group .cx-btn.cx-on {
|
|
background: var(--accent-soft); border-color: var(--accent); color: var(--accent-hi);
|
|
position: relative; z-index: 1; /* its border wins over its neighbours' */
|
|
}
|
|
|
|
.cx-btn-spin {
|
|
width: 11px; height: 11px; border-radius: var(--r-pill);
|
|
border: 2px 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); } }
|