/* Brightloop motion kit — the interaction layer shared by the studio page and every concept.
   Progressive only: with no JS, an old browser or reduced motion every page still shows all of its
   content and works; this file adds the transitions. A page sets its own colours through the
   custom properties below and keeps its own look. */

:root {
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --ease-back: cubic-bezier(.34, 1.4, .64, 1);
  --t-fast: 160ms;
  --t: 300ms;
  --t-slow: 600ms;
  --focus: currentColor;
  --ink-bg: currentColor;
}

/* page to page: the studio and its concepts cross-fade instead of flashing white */
@view-transition { navigation: auto; }
html:not([data-kit-swap])::view-transition-old(root) { animation: kit-out .22s var(--ease-in-out) both; }
html:not([data-kit-swap])::view-transition-new(root) { animation: kit-in .38s var(--ease-out) both; }
/* in-page swaps (Kit.swap): a plain cross-fade; with `{ page: false }` the page itself changes at once
   and only elements with a view-transition-name move, fade in or fade out */
html[data-kit-swap]::view-transition-group(*) { animation-duration: .42s; animation-timing-function: var(--ease-out); }
html[data-kit-swap="items"]::view-transition-old(root) { animation: none; opacity: 0; }
html[data-kit-swap="items"]::view-transition-new(root) { animation: none; }

html { scroll-behavior: smooth; scroll-padding-top: var(--scroll-pad, 84px); }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

/* press: everything you can tap gives under the finger. `scale` is its own property, so a page's
   own `transform` hover lift keeps working next to it */
:where(button, [role="button"], [role="tab"], .btn, summary, label:has(> input[type="radio"]),
       label:has(> input[type="checkbox"])) {
  -webkit-tap-highlight-color: transparent;
  transition: scale var(--t-fast) var(--ease-out), background-color var(--t) var(--ease-out),
              color var(--t) var(--ease-out), border-color var(--t) var(--ease-out),
              box-shadow var(--t) var(--ease-out), opacity var(--t) var(--ease-out),
              translate var(--t) var(--ease-out);
}
:where(button, [role="button"], [role="tab"], .btn):active:not(:disabled, [aria-disabled="true"]) {
  scale: .97;
}
/* an SVG shape that is a button gives under the finger from its own middle, not the SVG's corner */
:where(svg [role="button"]) { transform-box: fill-box; transform-origin: center; }
:where(input, select, textarea) {
  transition: border-color var(--t) var(--ease-out), box-shadow var(--t) var(--ease-out),
              background-color var(--t) var(--ease-out);
}

/* appears: an element shown by removing `hidden` (a tab panel, a step, a message) rises in;
   hiding it stays instant, so two panels never stand side by side */
[data-in] { transition: opacity var(--t) var(--ease-out), translate var(--t) var(--ease-out); }
@starting-style { [data-in]:not([hidden]) { opacity: 0; translate: 0 10px; } }

/* comes and goes: overlays, toasts, drawers, dialogs — animated both ways */
[data-io] {
  transition: opacity var(--t) var(--ease-out), translate var(--t) var(--ease-out),
              scale var(--t) var(--ease-out), display var(--t) allow-discrete,
              overlay var(--t) allow-discrete;
}
/* `display: none` again for `hidden`: a page's own `display: grid/flex` would otherwise keep it shown */
:is([data-io], [data-in])[hidden] { display: none; }
[data-io][hidden], dialog[data-io]:not([open]) { opacity: 0; translate: 0 12px; }
@starting-style {
  [data-io]:not([hidden]), dialog[data-io][open] { opacity: 0; translate: 0 12px; }
}
dialog[data-io]::backdrop {
  transition: background-color var(--t) var(--ease-out), display var(--t) allow-discrete,
              overlay var(--t) allow-discrete;
}

/* scroll reveal: only what starts below the fold, and only once (motion.js marks it) */
.kit-wait { opacity: 0; translate: 0 18px; }
.kit-show { transition: opacity .7s var(--ease-out), translate .7s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms); }

/* first paint: hero lines rise in once; under `animation: none` they simply stand */
[data-enter] { animation: kit-rise .8s var(--ease-out) both; animation-delay: calc(var(--d, 0) * 90ms); }

/* pictures fade in as they arrive instead of popping */
img.kit-load { opacity: 0; }
:where(img.kit-loaded) { transition: opacity .6s var(--ease-out); }   /* the page's own rules win */

/* the sliding marker under the active tab (Kit.ink) */
.kit-ink { position: absolute; left: 0; top: 0; width: 0; height: 0; pointer-events: none;
  background: var(--ink-bg); border-radius: var(--ink-radius, 999px); z-index: 0;
  transition: translate var(--t) var(--ease-out), width var(--t) var(--ease-out),
              height var(--t) var(--ease-out); }

/* a number or badge that just changed */
.kit-pop { animation: kit-pop .42s var(--ease-back); }

@keyframes kit-rise { from { opacity: 0; translate: 0 22px; } }
@keyframes kit-in { from { opacity: 0; } }
@keyframes kit-out { to { opacity: 0; } }
@keyframes kit-pop { 40% { scale: 1.18; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; transition-delay: 0s !important;
  }
  html { scroll-behavior: auto; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
