/* The height, rather than a min-height, is what bounds the middle track: the two chrome rows are
   pinned to the viewport and only the body between them scrolls. */
.o-appshell {
  height: 100svh;
  display: grid;
  grid-template-rows: var(--bar-h) 1fr var(--bar-h);
}
.o-appshell__body {
  overflow-y: auto;
  padding: var(--space-lg) var(--gutter-page) var(--space-2xl);
}
/* This element, not the window, is the scroll container, so an in-page #anchor jump moves it and
   the sticky bars offset against it. Smooth here because a jump on a dense page is otherwise an
   instant cut with nothing to tell a reader the contents link did anything. */
@media (prefers-reduced-motion: no-preference) {
  .o-appshell__body { scroll-behavior: smooth; }
}

.o-stack { display: flex; flex-direction: column; gap: var(--gap-stack); }
.o-stack--tight { gap: var(--space-sm); }
.o-stack--loose { gap: var(--space-xl); }

.o-cluster { display: flex; flex-wrap: wrap; gap: var(--gap-cluster); align-items: center; }
.o-cluster--tight { gap: var(--space-2xs); }

.o-repel { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; justify-content: space-between; }

.o-container { width: 100%; max-width: var(--shell-max); margin-inline: auto; }
.o-container--wide { max-width: var(--measure-wide); }

.o-measure { max-width: var(--measure); }

.o-grid { display: grid; gap: var(--gap-stack); grid-template-columns: repeat(auto-fit, minmax(min(100%, 28ch), 1fr)); }
.o-grid--two { grid-template-columns: repeat(auto-fit, minmax(min(100%, 40ch), 1fr)); }

/* Every split is one column until 56rem, which is --bp-md written out because a media query
   cannot read the token. The track is minmax(0, 1fr) and not 1fr because a grid track sized 1fr
   still floors at its content's min-content width: one item a phone cannot fit — a table, a
   box-drawing diagram, a terminal line with a long path in it — would otherwise widen the column
   past the viewport and take every paragraph beside it along. Floored at 0, the track is the
   container's width and the item that cannot fit scrolls or wraps inside itself. */
.o-split { display: grid; gap: var(--space-lg); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 56rem) { .o-split { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); } }
@media (min-width: 56rem) { .o-split--aside { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); } }
@media (min-width: 56rem) { .o-split--aside-left { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); } }
@media (min-width: 56rem) { .o-split--docs { grid-template-columns: 12rem minmax(0, 1fr); } }
