/* Motion.
 * ---------------------------------------------------------------------------
 * The theme animates almost everything at `0.5s ease`, and in a lot of places
 * as bare `transition: 0.5s ease`, which is `transition: all` - every property
 * that happens to change gets animated, layout-affecting ones included.
 *
 * Half a second is the reason the interface feels heavy: a hover that takes
 * 500ms to acknowledge a pointer reads as lag no matter what framerate it is
 * drawn at. Nothing here is about drawing more frames - the compositor already
 * runs at the display's refresh rate. It is about (a) shorter, and (b) animating
 * only what the compositor can handle on its own.
 *
 * The scale below is deliberately small. Anything that responds to a pointer is
 * --usr-fast, anything that moves a surface is --usr-panel, and the easing
 * decelerates so movement settles rather than stopping dead.
 *
 * Loaded last so it can retune the theme without editing it.
 * ------------------------------------------------------------------------- */

:root {
    --usr-fast: 130ms;
    --usr-base: 190ms;
    --usr-panel: 260ms;

    /* Decelerating: quick to start, gentle to land. */
    --usr-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    /* For surfaces that travel a long way, so they arrive without a bounce. */
    --usr-ease-panel: cubic-bezier(0.32, 0.72, 0, 1);
}

/* Bare `transition: 0.5s ease` on every link and button is `all` - it will
   animate a width or a margin if one ever changes. Name the properties. */
a:not(.USR_REACT a),
button:not(.USR_REACT button) {
    transition: color var(--usr-fast) var(--usr-ease),
                background-color var(--usr-fast) var(--usr-ease),
                border-color var(--usr-fast) var(--usr-ease),
                fill var(--usr-fast) var(--usr-ease),
                opacity var(--usr-fast) var(--usr-ease),
                transform var(--usr-fast) var(--usr-ease);
}

/* Icon and label colour changes across the chrome. Paint-only and cheap, but
   they were all half a second behind the pointer. */
.header__action-btn svg,
.header__action-btn span,
.header__nav-link,
.header__nav-link svg,
.header__profile-btn svg,
.header__profile-menu a,
.header__profile-menu a svg,
.main__nav svg,
.main__link svg,
.card__title,
.card__likes svg,
.card__likes span,
.asset__likes svg,
.asset__likes span,
.comments__actions button span,
.comments__actions button svg,
.footer__social a svg,
.footer__lang-btn span,
.contacts__social a svg,
.share__link svg {
    transition-duration: var(--usr-fast);
    transition-timing-function: var(--usr-ease);
}

/* Dropdowns: these only ever change opacity, so they are already composited -
   they were just slow. */
.header__profile-menu,
.header__nav-menu,
.footer__lang-dropdown {
    transition: opacity var(--usr-base) var(--usr-ease);
}

/* The burger's bars animate `width`, which is layout rather than compositing.
   Left alone: it is three 2px elements inside a 22px box, so the layout cost is
   nil, and replacing it with a scaleX would have to cancel the theme's own
   width change first or the two compound. Not worth the risk for three bars -
   just stop taking half a second over it. */
.header__btn span {
    transition: width var(--usr-base) var(--usr-ease),
                background-color var(--usr-fast) var(--usr-ease);
}

/* Cards lift on hover; keep it on the compositor and make it prompt. */
.gcard,
.serviceItem .service-card {
    transition: border-color var(--usr-fast) var(--usr-ease),
                transform var(--usr-fast) var(--usr-ease);
}

/* Surfaces that travel. */
.header__menu {
    transition: transform var(--usr-panel) var(--usr-ease-panel);
}

.bottom-sheet {
    transition: transform var(--usr-panel) var(--usr-ease-panel);
}

.bottom-sheet__backdrop {
    transition: opacity var(--usr-panel) var(--usr-ease);
}

.bottom-nav__item {
    transition: color var(--usr-fast) var(--usr-ease);
}

/* Hint the compositor only while a surface is actually moving. Left on
   permanently it costs memory for a layer nothing is animating, and on the
   drawer it would also make it a containing block for fixed children. */
.header__menu--active,
.bottom-sheet--open {
    will-change: transform;
}

/* content-visibility: auto on the cards is deliberately NOT here.
 * ---------------------------------------------------------------------------
 * It is the obvious next win - skip layout and paint for the cards that are off
 * screen. It was tried and taken back out, for two reasons and not the one it
 * first looked like: the cards went blank with it applied, but that turned out
 * to be the test browser not painting rather than anything the property did -
 * they were equally blank without it, and both recovered on a forced repaint.
 *
 * What stands is that it could not be verified here, and its failure mode is a
 * blank card. A listing page of blank cards is worse than any amount of scroll
 * cost. It also pays in proportion to the number of items, and these pages
 * render fifteen.
 *
 * If it is revisited: it needs `contain-intrinsic-size: auto <length>` so the
 * browser remembers each card's real height rather than shifting the scrollbar
 * from a guess (393px for a gaming or service card, 285px for a social one,
 * measured), and it needs checking against lazy-loaded covers, which live
 * inside the skipped subtree. */

/* Someone who has asked their system to reduce motion gets none of this. The
   theme already does this for its own transitions; this covers ours. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}
