@layer components {
  /* Footers — the row of actions at the bottom of a surface.
   *
   * A panel, a dialog, a popover and a combobox list all end the same way: the
   * actions pushed to the end, above a hairline, wrapping when they don't fit.
   * They were three copies of that rule and the copies had drifted:
   * .panel__footer was missing both the align-items that stops a small button
   * beside a normal one being stretched to a common height and the flex-wrap
   * that keeps a crowded footer on the screen, which the other two had and
   * documented. COMPONENTS.md said to fold them when a fourth arrived. This is
   * the fourth.
   *
   * What is genuinely per-surface is the padding, because a footer has to line
   * up with the gutters of the thing it sits in — a dialog's footer is inset by
   * the dialog's own padding, a panel's is not inset at all. So the shape is
   * declared once and each surface declares only its spacing, beneath.
   *
   * They keep their own names rather than sharing a .footer class. The name is
   * how you know which padding you are getting, and a footer with the wrong
   * padding for its surface is the bug this file exists to prevent.
   */
  .panel__footer,
  .dialog__footer,
  .popover__footer,
  .combobox__footer {
    display: flex;
    /* Stated, because the default is stretch: a footer holding a small button
       next to a normal one would pull them to a common height and undo the
       sizing every control does for itself. */
    align-items: center;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-half);
    border-block-start: var(--border);
  }

  /* Spacing, per surface. */

  .panel__footer {
    margin-block-start: var(--space-and-half);
    padding-block-start: var(--space);
  }

  /* Inset to the dialog's gutters, and part of the dialog rather than after it:
     the body is the only part that scrolls, so the footer carries the bottom
     padding the body gave up. */
  .dialog__footer {
    padding: var(--space) var(--space-and-half) var(--space-and-half);
  }

  .popover__footer {
    margin-block-start: var(--space-half);
    padding-block-start: var(--space-half);
  }

  /* Stays put while the options scroll past it, which is the whole reason a
     multi-select has one: the way out of a long list should not be at the
     bottom of the long list. Opaque, or the options would read through it. */
  .combobox__footer {
    position: sticky;
    inset-block-end: 0;
    padding: var(--space-half);
    background: var(--color-canvas);
  }
}
