/* ========================================================================== Niveus — Window -------------------------------------------------------------------------- .nv-window a framed application window .nv-window--inactive a window that does not have focus .nv-window__titlebar controls · title · trailing actions .nv-window__controls the three lights, at the start of the bar .nv-window__control one light: --close, --minimize or --zoom .nv-window__title the window's name, centered on the bar .nv-window__actions trailing slot for a few ghost buttons .nv-window__body the content area
Settings
…
A window is a solid object: the content it holds never sits on glass. Its titlebar is a raised strip lit like a control, and the controls are three lights at its start — close, minimize, zoom — always in that order and in those colors, because people find them by position and color before they read anything. Their glyphs appear only while the pointer is over the group. An inactive window greys its lights and steps back one elevation, and the lights regain their color the moment they are hovered. ========================================================================== */ .nv-window { display: flex; flex-direction: column; min-inline-size: 0; background-color: var(--nv-color-surface); background-image: var(--nv-sheen-surface); color: var(--nv-color-text-primary); border: var(--nv-border-width) solid var(--nv-color-border-subtle); border-radius: var(--nv-radius-xl); box-shadow: var(--nv-highlight-top), var(--nv-outline), var(--nv-elevation-4); overflow: hidden; transition: var(--nv-transition-surface); } .nv-window--inactive { box-shadow: var(--nv-highlight-top), var(--nv-outline), var(--nv-elevation-3); } /* --- Titlebar --------------------------------------------------------------- Three columns with the outer two sharing the slack, so the title stays on the window's center line whatever the controls and actions measure. */ .nv-window__titlebar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--nv-space-3); /* Slim, as titlebars on the desktop are: tall enough for the lights and a label, not a toolbar's height. */ min-block-size: calc(var(--nv-control-height-sm) + var(--nv-space-1)); padding-inline: var(--nv-space-3); background-color: var(--nv-color-surface-elevated); background-image: var(--nv-sheen-raised); border-block-end: var(--nv-border-width) solid var(--nv-color-border-subtle); box-shadow: var(--nv-highlight-top); user-select: none; } .nv-window__title { grid-column: 2; min-inline-size: 0; overflow: hidden; font: var(--nv-font-label); font-weight: var(--nv-font-weight-semibold); color: var(--nv-color-text-primary); text-overflow: ellipsis; white-space: nowrap; } .nv-window--inactive .nv-window__title { color: var(--nv-color-text-tertiary); } .nv-window__actions { grid-column: 3; justify-self: end; display: flex; align-items: center; gap: var(--nv-space-1); } /* --- Controls ----------------------------------------------------------------- */ .nv-window__controls { grid-column: 1; justify-self: start; display: flex; align-items: center; gap: var(--nv-space-2); } .nv-window__control { --_light: var(--nv-color-window-close); --_c: var(--_light); position: relative; flex: none; inline-size: var(--nv-space-3); block-size: var(--nv-space-3); margin: 0; padding: 0; background-color: var(--_c); background-image: var(--nv-sheen-filled); border: 0; border-radius: var(--nv-radius-full); box-shadow: inset 0 0 0 var(--nv-border-width) var(--nv-color-window-control-ring); cursor: pointer; appearance: none; -webkit-tap-highlight-color: transparent; transition: var(--nv-transition-colors); } .nv-window__control--minimize { --_light: var(--nv-color-window-minimize); } .nv-window__control--zoom { --_light: var(--nv-color-window-zoom); } /* The glyph is two bars drawn from the light's center: crossed for close, one for minimize, a plus for zoom. They are always present and fade in, so the whole group reveals at once instead of one glyph at a time. */ .nv-window__control::before, .nv-window__control::after { content: ""; position: absolute; inset-block-start: 50%; inset-inline-start: 50%; inline-size: 55%; block-size: calc(var(--nv-border-width) * 1.5); translate: -50% -50%; background-color: var(--nv-color-window-glyph); border-radius: var(--nv-radius-full); opacity: 0; transition: opacity var(--nv-duration-fast) var(--nv-ease-standard); } .nv-window__control--close::before { rotate: 45deg; } .nv-window__control--close::after { rotate: -45deg; } .nv-window__control--minimize::after { display: none; } .nv-window__control--zoom::after { rotate: 90deg; } .nv-window__controls:hover .nv-window__control::before, .nv-window__controls:hover .nv-window__control::after, .nv-window__controls:focus-within .nv-window__control::before, .nv-window__controls:focus-within .nv-window__control::after { opacity: 1; } .nv-window__control:active { background-image: none; box-shadow: inset 0 0 0 var(--nv-border-width) var(--nv-color-window-control-ring), var(--nv-elevation-inset-sm); } .nv-window__control:focus-visible { outline: none; box-shadow: inset 0 0 0 var(--nv-border-width) var(--nv-color-window-control-ring), var(--nv-focus-ring); } .nv-window--inactive .nv-window__control { --_c: var(--nv-color-window-inactive); } .nv-window--inactive .nv-window__controls:hover .nv-window__control { --_c: var(--_light); } /* --- Body --------------------------------------------------------------------- */ .nv-window__body { flex: 1; min-block-size: 0; overflow: auto; }