/**
 * At most --dynamic-grid-count equal columns, folding to fewer as soon as a column would get
 * narrower than --dynamic-grid-min. Children opt into spanning with .grid-span-N,
 * clamped to however many columns actually fit.
 *
 * Deliberately standalone from .grid-with-columns: the file galleries depend on that
 * component's exact behaviour and on it not being an inline-size container, so the two are
 * kept apart instead of cross-wired through shared modifier classes.
 */
.dynamic-grid {
    /* A high default is the "no column cap" case: the grid then folds on --dynamic-grid-min alone */
    --dynamic-grid-count: 100;
    --dynamic-grid-min: 150px;
    --dynamic-grid-gap: 0;
    /*
     * One column's share of a full N-column row. Whichever of this and --dynamic-grid-min is
     * larger becomes the track floor: while the share is larger, auto-fill fits exactly N
     * tracks; once it drops below the min, the min takes over and a column is dropped.
     * The .5px stops subpixel rounding from landing one track short of N.
     */
    --dynamic-grid-share: calc(
        (100% - (var(--dynamic-grid-count) - 1) * var(--dynamic-grid-gap)) / var(--dynamic-grid-count) - .5px
    );
    display: grid;
    gap: var(--dynamic-grid-gap) !important; /* Need !important to overrule Bootstrap's gap css */
    /* auto-fit collapses the tracks no item landed in, so a short row stretches to the full width */
    grid-template-columns: repeat(
        auto-fit,
        minmax(min(max(var(--dynamic-grid-min), var(--dynamic-grid-share)), 100%), 1fr)
    );
    container-type: inline-size;
    /* Pass Bootstrap's gap-... classes to css variables */
    &.gap-1 { --dynamic-grid-gap: .25rem; }
    &.gap-2 { --dynamic-grid-gap: .5rem; }
    &.gap-3 { --dynamic-grid-gap: 1rem; }
    &.gap-4 { --dynamic-grid-gap: 1.5rem; }
    &.gap-5 { --dynamic-grid-gap: 3rem; }
    > * {
        /*
         * 100cqi has to be read from a child: an element is never its own container, so this
         * same calc declared on .dynamic-grid would measure an ancestor container instead
         */
        --dynamic-grid-columns: min(
            var(--dynamic-grid-count),
            (100cqi + var(--dynamic-grid-gap)) / (var(--dynamic-grid-min) + var(--dynamic-grid-gap))
        );
    }
    /* Clamp to the actual column count, or a span too large creates an extra implicit (undersized) column */
    > .grid-span-2 { grid-column: span round(down, clamp(1, var(--dynamic-grid-columns), 2), 1); }
    > .grid-span-3 { grid-column: span round(down, clamp(1, var(--dynamic-grid-columns), 3), 1); }
    > .grid-span-4 { grid-column: span round(down, clamp(1, var(--dynamic-grid-columns), 4), 1); }
}
