Ran v4 side by side to see what the difference actually was, and it was not spacing. v4 fills the window edge to edge and divides its zones with hairlines; v5 floated rounded, shadowed cards on a visible page background. One reads as an editing suite, the other as a dashboard. So panel gains a second variant. "default" is still a card, for something that floats -- inside a window, on a page. "zone" is a region of the app: square, no shadow, no border of its own, divided from its neighbours by the one hairline everything else uses. The workspace keeps no gutter between regions; the preview zone is flush, because padding around a picture is a frame nobody asked for, and its surround is letterbox black rather than a panel colour. The right column was two stacked panels with two heads for one thing. It is one zone now. And the surfaces have depth, derived from each theme's own elevation scale so neither needs a rule of its own: a vertical fall on every band and every raised control, the accent gradient and a bloom under a primary button, a wash off the top-right of the page, tokenised thin scrollbars, an accent mark on every zone title, and v4's film grain -- overlay at 3.5% on dark, multiply at 1.5% on light, and painted with no z-index so anything that opens above the frame stays crisp.
68 lines
3.7 KiB
CSS
68 lines
3.7 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);
|
|
}
|
|
/* Brightened rather than repainted: a second accent colour for hover is a
|
|
second thing to keep in step with the first, and this one cannot drift. */
|
|
.cx-btn-primary:hover:not(:disabled) { filter: brightness(1.08); }
|
|
|
|
.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); } }
|