/*
  Application layout: three regions on one grid.
    #rail   var(--rail-w), 72px; body[data-rail="open"] widens it to 240px and shows the labels.
    #stage  fluid, and the scroll container for page content.
    #ops    var(--ops-w): 360px, 440px from 2560px wide.
  Overflow is prevented by the layout (minmax(0, 1fr) and per-region scrolling); it is never hidden
  on html or body.
*/

body {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--ops-w);
  grid-template-rows: minmax(0, 1fr);
  height: 100dvh;
}

body[data-rail="open"] {
  --rail-w: var(--rail-w-open);
}

#rail,
#stage,
#ops {
  min-width: 0;
  min-height: 0;
}

#stage {
  /* Keep absolute accessibility/live-region nodes inside this scrolling region. */
  position: relative;
  overflow-y: auto;
  scrollbar-gutter: stable;
  padding: var(--s-6) var(--s-7);
}

#ops {
  overflow-y: auto;
  padding: var(--s-5);
  border-left: 1px solid var(--line);
  background-color: var(--bg-1);
}

#stage,
#ops,
.stage-split > * {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--fg-2) 50%, transparent) transparent;
}

/* Rail. It does not scroll, so the collapsed labels can fly out over the stage. */
#rail {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  padding: var(--s-4) 0;
  border-right: 1px solid var(--line);
  background-color: var(--bg-1);
}

.rail-nav,
.rail-foot {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.rail-foot {
  margin-top: auto;
}

/* An <a> or <button>: a 24px icon then a .rail-label. The icon stays put when the rail opens. */
.rail-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-4);
  height: 44px;
  margin: 0 var(--s-3);
  padding: 0 var(--s-3);
  border: 0;
  border-radius: var(--r-2);
  background-color: transparent;
  color: var(--fg-2);
  font-size: var(--fs-1);
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}

.rail-link .icon {
  width: 24px;
  height: 24px;
  transition: rotate var(--t-med) var(--ease);
}

.rail-link:hover {
  background-color: var(--bg-2);
  color: var(--fg-0);
}

.rail-link[aria-current="page"] {
  background-color: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--fg-0);
}

.rail-link[aria-current="page"] .icon {
  color: var(--accent);
}

.rail-link[aria-current="page"]::before {
  content: "";
  position: absolute;
  top: 10px;
  bottom: 10px;
  left: calc(-1 * var(--s-3));
  width: 3px;
  border-radius: 0 3px 3px 0;
  background-color: var(--accent);
}

/* The open/close control carries aria-expanded; its chevron turns to point back. */
.rail-link[aria-expanded="true"] .icon {
  rotate: 180deg;
}

.rail-label {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Collapsed: the label is a flyout beside the icon, shown on hover and keyboard focus. */
body:not([data-rail="open"]) .rail-label {
  position: absolute;
  top: 50%;
  left: calc(100% + var(--s-4));
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-1);
  background-color: var(--fg-0);
  color: var(--bg-0);
  font-size: var(--fs-0);
  font-weight: 600;
  box-shadow: var(--shadow-2);
  opacity: 0;
  pointer-events: none;
  translate: -4px -50%;
  transition: opacity var(--t-fast) var(--ease), translate var(--t-fast) var(--ease);
}

body:not([data-rail="open"]) .rail-link:is(:hover, :focus-visible) .rail-label {
  opacity: 1;
  translate: 0 -50%;
}

/*
  Opt-in split stage: from 3440px wide, .stage-split shows its children side by side (a brief beside
  its lab), each scrolling on its own. Make it the only child of #stage. Narrower, the children stack.
*/
.stage-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-7);
}

@media (min-width: 3440px) {
  .stage-split {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    height: 100%;
  }

  .stage-split > * {
    min-height: 0;
    overflow-y: auto;
    scrollbar-gutter: stable;
  }
}

/* Layout primitives. Override a gap with style: { gap: 'var(--s-6)' }. */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
}

/* Auto-filling columns at least --grid-min wide (default 280px). */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--grid-min, 280px), 100%), 1fr));
  gap: var(--s-5);
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-5);
}

.grid > *,
.grid-2 > * {
  min-width: 0;
}
