/* Compositions: how things sit together, never how they look. Each takes its
   spacing from one custom property with a token default, so a page tunes a
   layout with a style or utility instead of a new rule. Most adapt to their
   own width instead of the viewport. */

/* Vertical rhythm between children, tuned with --flow-space. A gap rather
   than margins on the children, so the space belongs to this element: a child
   that is itself a .flow with its own --flow-space can't change it. */
.flow {
  display: flex;
  flex-direction: column;
  gap: var(--flow-space, var(--space-s));
}

/* Horizontal group that wraps: buttons, chips, meta lines */
.cluster {
  align-items: var(--cluster-align, center);
  display: flex;
  flex-wrap: wrap;
  gap: var(--cluster-space, var(--space-xs));
  justify-content: var(--cluster-justify, flex-start);
}

/* Two ends pushed apart: a title and its action, a label and its value */
.repel {
  align-items: var(--repel-align, center);
  display: flex;
  flex-wrap: wrap;
  gap: var(--repel-space, var(--space-xs));
  justify-content: space-between;
}

/* Rows that become a column once one would get narrower than --switcher-at */
.switcher {
  display: flex;
  flex-wrap: wrap;
  gap: var(--switcher-space, var(--gutter));

  & > * {
    flex-basis: calc((var(--switcher-at, 30rem) - 100%) * 999);
    flex-grow: 1;
  }
}

/* A fixed-width side beside a flexible main that wraps under it when the
   main would drop below --sidebar-content-min */
.with-sidebar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sidebar-space, var(--gutter));

  & > :first-child {
    flex-basis: var(--sidebar-width, 18rem);
    flex-grow: 1;
  }

  & > :last-child {
    flex-basis: 0;
    flex-grow: 999;
    min-inline-size: var(--sidebar-content-min, 55%);
  }
}

/* As many columns as fit at --auto-grid-min each */
.auto-grid {
  display: grid;
  gap: var(--auto-grid-space, var(--gutter));
  grid-template-columns: repeat(auto-fill, minmax(min(var(--auto-grid-min, 14rem), 100%), 1fr));
}

/* Page-width container with side gutters */
.wrapper {
  margin-inline: auto;
  max-inline-size: var(--wrapper-width, var(--wrapper-max));
  padding-inline: var(--wrapper-gutter, var(--gutter));
  width: 100%;
}

/* A page region: vertical breathing room between bands */
.region {
  padding-block: var(--region-space, var(--space-l-xl));
}

/* Media held to a ratio */
.frame {
  aspect-ratio: var(--frame-ratio, 16 / 9);
  overflow: hidden;

  & > :is(img, video, iframe) {
    block-size: 100%;
    inline-size: 100%;
    object-fit: cover;
  }
}
