123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 | /* Base bar styling. Widget-specific styles live in each widget module
and are injected by the registry, so this file only styles the shell. */
:root {
/* Set at runtime by main.js from the bar config (height / padding);
these are fallbacks. Everything below scales from --chip-height,
which is bar height minus vertical padding. */
--bar-height: 48px;
--bar-pad-x: 10px;
--bar-pad-y: 6px;
--chip-height: 36px;
--chip-radius: 18px;
--bar-font: 20px;
--icon-size: 32px;
--bar-bg: rgba(16, 18, 24, 0.92);
/* Subtle vertical gradient: faintly lifted at the top, settling darker
at the bottom edge. */
--bar-bg-top: rgba(25, 28, 36, 0.93);
--bar-bg-mid: rgba(16, 18, 24, 0.92);
--bar-bg-bottom: rgba(13, 15, 20, 0.93);
--bar-fg: #8f96a5;
--bar-fg-dim: #626a79;
--accent: #7aa2f7;
--warn: #e0af68;
--critical: #f7768e;
--chip-bg: rgba(255, 255, 255, 0.06);
--chip-bg-hover: rgba(255, 255, 255, 0.12);
--font: "Inter", "Cantarell", system-ui, sans-serif;
--font-mono: "JetBrains Mono", "Fira Code", monospace;
}
/* Without a compositor, alpha renders against black — use opaque colors. */
:root.no-compositor {
--bar-bg: rgb(18, 20, 26);
--bar-bg-top: rgb(25, 28, 36);
--bar-bg-mid: rgb(16, 18, 24);
--bar-bg-bottom: rgb(13, 15, 20);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
html,
body {
height: 100%;
overflow: hidden;
background: transparent;
}
/* One flex row: every widget sizes to its content; anything that should
absorb spare space (window-title by default) sets flex-grow itself. */
#bar {
height: var(--bar-height);
display: flex;
align-items: center;
gap: 4px;
padding: var(--bar-pad-y) var(--bar-pad-x);
background: linear-gradient(
180deg,
var(--bar-bg-top) 0%,
var(--bar-bg-mid) 55%,
var(--bar-bg-bottom) 100%
);
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
/* Hairline highlight along the top edge sells the gradient. */
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
color: var(--bar-fg);
font-family: var(--font);
font-size: var(--bar-font);
}
/* Shared look for widgets that opt into the "chip" class */
.chip {
display: flex;
align-items: center;
gap: 5px;
height: var(--chip-height);
padding: 0 calc(var(--chip-height) * 0.22);
border-radius: var(--chip-radius);
white-space: nowrap;
transition: background 120ms ease;
}
/* Only interactive chips (marked .clickable) show a hover background. */
.chip.clickable:hover {
background: var(--chip-bg-hover);
}
/* Fitts's law: every clickable element keeps its visual padding but gets
an invisible overlay (its ::after) that spans the full bar height and
meets its neighbours halfway across the gap, so there are no dead zones.
The overlay is a child of the element, so clicks, hover and tooltips all
land on the element itself; z-index -1 (inside the element's own
stacking context) keeps it beneath any real content the element has.
Clickable chips get this automatically. Buttons nested inside a widget
opt in with the `hit-target` class, and the widget describes its
geometry through variables:
--hit-inset-x / --hit-inset-y distance from the button to the
widget's outer edge (default 0)
--hit-gap-x half the gap between siblings
(default 2px: half the #bar gap) */
#bar .chip.clickable,
#bar .hit-target {
position: relative;
isolation: isolate;
}
#bar .chip.clickable::after,
#bar .hit-target::after {
content: "";
position: absolute;
z-index: -1;
top: calc(-1 * (var(--bar-pad-y) + var(--hit-inset-y, 0px)));
bottom: calc(-1 * (var(--bar-pad-y) + var(--hit-inset-y, 0px)));
left: calc(-1 * var(--hit-gap-x, 2px));
right: calc(-1 * var(--hit-gap-x, 2px));
}
/* The outermost nested buttons also cover their widget's padding and
half the #bar gap beyond it. */
#bar .hit-target:first-child::after {
left: calc(-1 * (var(--hit-inset-x, 0px) + 2px));
}
#bar .hit-target:last-child::after {
right: calc(-1 * (var(--hit-inset-x, 0px) + 2px));
}
/* At either end of the bar the hitbox runs through the bar padding to the
window edge, so the screen edge and corners themselves are clickable. */
#bar > :first-child.chip.clickable::after,
#bar > :first-child .hit-target:first-child::after {
left: calc(-1 * (var(--bar-pad-x) + var(--hit-inset-x, 0px)));
}
#bar > :last-child.chip.clickable::after,
#bar > :last-child .hit-target:last-child::after {
right: calc(-1 * (var(--bar-pad-x) + var(--hit-inset-x, 0px)));
}
.chip .icon {
display: flex;
align-items: center;
justify-content: center;
font-size: var(--bar-font);
line-height: 1;
}
.chip .icon svg {
display: block;
width: var(--icon-size);
height: var(--icon-size);
}
.chip .value {
font-family: var(--font-mono);
font-size: var(--bar-font);
font-variant-numeric: tabular-nums;
}
|