/**
 * <frame-ui> — sticky-header / scroll-body / sticky-footer layout frame.
 *
 * The chrome-less app-shell skeleton: a flex column that fills its parent's
 * block size. A native <header> child pins to the top, a <footer> child pins
 * to the bottom, and the <section> child scrolls between them (the only region
 * with overflow). All three regions are OPTIONAL and positioned by tag + DOM
 * order — Light DOM, no slot projection (ADR-0033). <card-ui> / <drawer-ui> /
 * <modal-ui> layer chrome (border / elevation / backdrop) over this same
 * region contract.
 *
 * Height: frame-ui fills its parent, so the parent must establish a definite
 * block size (a flex/grid chain rooted at a viewport height, or an explicit
 * height). In a content-sized parent it collapses to its content and the
 * <section> simply doesn't scroll (graceful, not broken).
 */
@scope (frame-ui) {
  :where(:scope) {
    display: flex;
    flex-direction: column;
    block-size: 100%;
    min-block-size: 0;
  }

  /* Pinned rails — native <header>/<footer>, OR any element that opts into the role
     via slot="header"/"footer" (the drawer-ui pattern), so e.g. a <section slot="header">
     becomes a pinned rail rather than the scroll body. Fixed height, never scroll. */
  :scope > :is(header, footer, [slot="header"], [slot="footer"]) {
    flex: 0 0 auto;
    min-block-size: 0;
  }

  /* The single scroll region — native <section> OR slot="body", minus anything that
     opted into a rail role above. `min-block-size: 0` lets the flex item shrink below
     its content's intrinsic size — the flex-scroll gotcha that makes overflow:auto
     actually scroll inside a column. */
  :scope > :is(section, [slot="body"]):not([slot="header"]):not([slot="footer"]) {
    flex: 1 1 auto;
    min-block-size: 0;
    overflow: auto;
  }
}
