/* Motion: short and quiet, to show where a thing came from and went. Every
   transition here goes away when the system asks for reduced motion, and
   nothing moves while the page first loads (html.no-anim). */

:root {
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --t-fast: 140ms;
  --t: 220ms;
}

/* ---------------------------------------------------------------- controls */

.button, .icon-button, .segmented > a, .segmented > button, .lib-item, .locale-item, .step-link, .app-card, .st {
  transition: background-color var(--t-fast) ease, color var(--t-fast) ease, box-shadow var(--t-fast) ease, border-color var(--t-fast) ease, opacity var(--t-fast) ease;
}
.button:active:not(:disabled) { transform: scale(0.98); }

/* ---------------------------------------------------------------- overlays */

.modal { opacity: 0; transition: opacity var(--t) ease; }
.modal.is-open { opacity: 1; }
.modal-box { transform: translateY(10px) scale(0.97); transition: transform var(--t) var(--ease-out); }
.modal.is-open .modal-box { transform: none; }
.modal.is-closing { transition-duration: var(--t-fast); }
.modal.is-closing .modal-box { transform: scale(0.98); transition-duration: var(--t-fast); }
.lightbox-img { transition: opacity var(--t-fast) ease; }
.lightbox-img.is-loading { opacity: 0.35; }

.toast { opacity: 0; transform: translateY(8px); transition: opacity var(--t) ease, transform var(--t) var(--ease-out); }
.toast.is-shown { opacity: 1; transform: none; }

.menu-list { transform-origin: top right; opacity: 0; transform: scale(0.96) translateY(-4px); transition: opacity var(--t-fast) ease, transform var(--t-fast) var(--ease-out); }
.menu-list.is-open { opacity: 1; transform: none; }

/* ---------------------------------------------------------------- page changes */

.main.is-entering { animation: page-in var(--t) var(--ease-out); }
@keyframes page-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------------------------------------------------------------- the set dock folds */

.dock-body { display: grid; grid-template-rows: 1fr; opacity: 1; transition: grid-template-rows var(--t) var(--ease-out), opacity var(--t) ease; }
.dock-body > div { min-height: 0; overflow: hidden; }
.dock.is-collapsed .dock-body { grid-template-rows: 0fr; opacity: 0; }

/* ---------------------------------------------------------------- the sidebar folds to icons */

.app { transition: grid-template-columns var(--t) var(--ease-out); }
.lib-name, .brand-name, .sidebar-label, .keys { transition: opacity var(--t-fast) ease; }

/* ---------------------------------------------------------------- swipes stay put */

/* A sideways scroller that reaches its end must not hand the swipe to the
   browser, which would go back a page; with an overlay open, the page under
   it never takes one. */
.as-shots, .strip, .dock-strip, .thumbs, .matrix-wrap, .step-bar, .search-row, .locale-list, .modal-box { overscroll-behavior-x: contain; }
html:has(.modal), html:has(.modal) body { overscroll-behavior-x: none; }

/* ---------------------------------------------------------------- less motion */

html.no-anim *, html.no-anim *::before, html.no-anim *::after { transition: none !important; animation: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; }
  .button:active:not(:disabled) { transform: none; }
}
