.tabs { display: grid; grid-template-rows: auto 1fr; min-height: 0; } /* The strip is the panel's own canvas: the active tab is a rounded chip lying ON it, as in fleet.png. An earlier round cut the tab out of a chrome plate instead; the owner prefers this. */ .row { display: flex; gap: var(--space-1); align-items: center; padding: var(--panel-padding) var(--panel-padding) 0; } /* The row scrolls instead of shrinking its tabs. Flex shrink distributed the overflow in proportion to each tab's width, so a SHORT title could ellipsize while a longer neighbour did not — the defect the owner reported. */ .list { display: flex; gap: var(--space-1); min-width: 0; overflow-x: auto; scrollbar-width: none; } .tab { display: flex; height: var(--panel-header-height); max-width: var(--tab-width-max); flex: none; align-items: center; padding-inline: var(--tab-inset); gap: var(--space-2); border-radius: var(--radius-control); color: var(--color-text-secondary); white-space: nowrap; cursor: pointer; } .tab[data-hovered] { color: var(--color-text); } .tab[data-selected] { background-color: var(--color-raised); color: var(--color-text); } /* An open document reads blue where a tool tab reads grey: fleet.png draws that distinction with the fill itself, not with a mark along an edge. */ .row[data-look='document'] .tab[data-selected] { background-color: var(--color-tab-active); } .tab .title { overflow: hidden; text-overflow: ellipsis; } /* Preview is italic, as in VS Code: the tab is temporary and will be replaced by the next click. */ .tab[data-preview='true'] .title { font-style: italic; } .tab[data-focus-visible] { outline: 1px solid var(--color-accent); outline-offset: -1px; } /* The close mark shows on the selected and hovered tab only. Its space is reserved always (visibility, not display), or the row would jump on every switch. */ .close { display: flex; flex: none; align-items: center; border-radius: var(--radius-control); color: var(--color-text-muted); visibility: hidden; cursor: pointer; } .close:hover { color: var(--color-text); } .tab[data-selected] .close, .tab[data-hovered] .close { visibility: visible; } /* «+» follows the tabs but stays OUT of the scrolling list, so it cannot scroll away from them. */ .add { display: flex; flex: none; align-items: center; padding-inline: var(--space-1); } /* All the panels live in the SECOND grid row and lie on top of one another: with keepAlive they are rendered at the same time, and without an explicit place the unselected ones would create new grid rows. */ .panel { display: flex; grid-row: 2; grid-column: 1; flex-direction: column; min-height: 0; /* The scroll lives inside the tab's content: long lists are virtualized and scroll themselves. */ overflow: hidden; padding: var(--space-1) var(--panel-padding) var(--panel-padding); } /* An unselected keep-alive panel: `content-visibility: hidden` skips layout and paint while keeping state — `display: none` would destroy the scroll offset, `visibility: hidden` would still lay the subtree out on every resize (that is what made the right separator drag twice as costly). */ .panel[data-inert] { content-visibility: hidden; }