/**
 * Deconiq scroller utility
 *
 * Add the class `dq-scroll` to any element whose content overflows sideways.
 * JS keeps three state classes on it:
 *   is-scrollable - the content really does overflow right now
 *   at-start      - scrolled fully left
 *   at-end        - scrolled fully right
 *
 * The edge fade is bound to those states, so nothing shows up when there is
 * nothing to scroll, and the fade only appears on the side that has more
 * content. No scrollbar: the fade is the affordance.
 */
.dq-scroll {
    --dq-fade: 2.5rem;

    overflow-x: auto;
    overflow-y: hidden;
    /* Keep a horizontal swipe from turning into a browser back gesture. */
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.dq-scroll::-webkit-scrollbar { display: none; }

/* Both edges: there is content in both directions. */
.dq-scroll.is-scrollable {
    -webkit-mask-image: linear-gradient(
        to right,
        transparent 0,
        #000 var(--dq-fade),
        #000 calc(100% - var(--dq-fade)),
        transparent 100%
    );
    mask-image: linear-gradient(
        to right,
        transparent 0,
        #000 var(--dq-fade),
        #000 calc(100% - var(--dq-fade)),
        transparent 100%
    );
}

/* At the very start: only hint to the right. */
.dq-scroll.is-scrollable.at-start {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--dq-fade)), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - var(--dq-fade)), transparent 100%);
}

/* At the very end: only hint to the left. */
.dq-scroll.is-scrollable.at-end {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--dq-fade));
    mask-image: linear-gradient(to right, transparent 0, #000 var(--dq-fade));
}

/* Safety: both ends at once means it does not actually scroll. */
.dq-scroll.is-scrollable.at-start.at-end {
    -webkit-mask-image: none;
    mask-image: none;
}
