/* ChemicallyFired — interaction layer (2026-09-24). Loaded on every public
   page by the middleware, for both themes. Precise, restrained motion:
   - buttons compress slightly on press, springing back
   - cards lift a hair on hover (pointer devices only)
   - one consistent focus ring
   - page-to-page transitions (cross-document View Transitions), with the
     clicked product/project image morphing into the page it opens
   Everything uses the individual `scale` / `translate` properties so it never
   fights a component's own `transform`. Reduced motion turns all of it off. */

:root {
  --ux-focus: #13745f;
  /* Critically-damped-ish spring, sampled (falls back to an ease-out). */
  --ux-spring: cubic-bezier(0.2, 0.9, 0.25, 1.15);
  --ux-press: cubic-bezier(0.3, 0, 0.3, 1);
}

@supports (transition-timing-function: linear(0, 1)) {
  :root {
    --ux-spring: linear(0, 0.157, 0.44, 0.681, 0.857, 0.968, 1.03, 1.057, 1.061, 1.052, 1.037, 1.021, 1.008, 0.999, 0.994, 0.992, 0.993, 0.995, 0.998, 1);
  }
}

html[data-theme="precision-lab"] {
  --ux-focus: #ff5a1f;
}

/* Press: buttons and button-like controls compress ~3%. ------------------- */
:where(.button, .btn, .nav-button, .cart-button, .menu-button, .lab3d-chip, .lab3d-exit, .music-switch, .shop-card-add, .pdp-thumb, .orb-seg button, .orb-chips button, .orb-stepper button, .chip, [role="button"], button:not(:disabled)) {
  transition-property: scale, translate, background-color, border-color, color, box-shadow, opacity;
  transition-duration: 420ms, 420ms, 180ms, 180ms, 180ms, 220ms, 180ms;
  transition-timing-function: var(--ux-spring), var(--ux-spring), ease, ease, ease, ease, ease;
}

:where(.button, .btn, .nav-button, .cart-button, .menu-button, .lab3d-chip, .lab3d-exit, .shop-card-add, .pdp-thumb, .orb-seg button, .orb-chips button, .orb-stepper button, .chip, [role="button"], button:not(:disabled)):active {
  scale: 0.97;
  transition-duration: 90ms;
  transition-timing-function: var(--ux-press);
}

/* Hover lift for primary buttons (pointer devices). */
@media (hover: hover) and (pointer: fine) {
  :where(.button, .nav-button, .lab3d-exit):hover {
    translate: 0 -1px;
  }
  :where(.button, .nav-button, .lab3d-exit):hover:active {
    translate: 0 0;
  }
}

/* Cards: a precise 3px lift + deeper shadow on hover. ---------------------- */
@media (hover: hover) and (pointer: fine) {
  :where(.shop-card, .product-card, .project-card, .lab-card, .fp-work, .fp-link, .orb-shop) {
    transition: translate 460ms var(--ux-spring), box-shadow 260ms ease, border-color 200ms ease;
  }
  :where(.shop-card, .product-card, .project-card, .lab-card, .fp-work):hover {
    translate: 0 -3px;
  }
  :where(.shop-card, .product-card, .project-card, .lab-card, .fp-work):active {
    translate: 0 -1px;
    scale: 0.995;
    transition-duration: 120ms;
  }
}

/* Focus: one clear ring everywhere (keyboard only). ----------------------- */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ux-focus);
  outline-offset: 3px;
}

/* Navigation: underline that draws in from the left. ----------------------- */
.desktop-nav a:not(.nav-button) {
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 0% 1px;
  transition: background-size 380ms var(--ux-spring), color 160ms ease;
}

.desktop-nav a:not(.nav-button):hover,
.desktop-nav a:not(.nav-button):focus-visible {
  background-size: 100% 1px;
}

/* Mobile menu: slides + fades in instead of popping. ----------------------- */
.mobile-nav:not([hidden]) {
  animation: ux-menu-in 320ms var(--ux-spring) both;
}

.mobile-nav:not([hidden]) a {
  animation: ux-menu-item 360ms var(--ux-spring) both;
}

.mobile-nav:not([hidden]) a:nth-child(2) { animation-delay: 30ms; }
.mobile-nav:not([hidden]) a:nth-child(3) { animation-delay: 60ms; }
.mobile-nav:not([hidden]) a:nth-child(4) { animation-delay: 90ms; }
.mobile-nav:not([hidden]) a:nth-child(5) { animation-delay: 120ms; }
.mobile-nav:not([hidden]) a:nth-child(6) { animation-delay: 150ms; }
.mobile-nav:not([hidden]) a:nth-child(n+7) { animation-delay: 180ms; }

@keyframes ux-menu-in {
  from { opacity: 0; translate: 0 -8px; }
  to { opacity: 1; translate: 0 0; }
}

@keyframes ux-menu-item {
  from { opacity: 0; translate: 0 6px; }
  to { opacity: 1; translate: 0 0; }
}

/* Toggles: the knob springs across. ---------------------------------------- */
.music-switch-knob,
.orb-spin {
  transition: transform 420ms var(--ux-spring), translate 420ms var(--ux-spring), background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}

/* Sound toggle (added to the footer by ux.js when interface sounds are on). */
.ux-sound-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  opacity: 0.8;
}

.ux-sound-toggle:hover {
  opacity: 1;
}

.ux-sound-toggle svg {
  width: 14px;
  height: 14px;
}

/* Page transitions ----------------------------------------------------------
   Browsers with cross-document View Transitions (Chrome/Edge 126+, Safari
   18.2+) cross-fade between pages with a slight rise; the clicked card image
   (named cf-media by ux.js) morphs into the product photo on the next page.
   Other browsers simply navigate as before. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }

  ::view-transition-old(root) {
    animation: 180ms ease-in both ux-vt-out;
  }

  ::view-transition-new(root) {
    animation: 320ms cubic-bezier(0.2, 0.8, 0.2, 1) 60ms both ux-vt-in;
  }

  ::view-transition-group(cf-media),
  ::view-transition-group(cf-title) {
    animation-duration: 520ms;
    animation-timing-function: cubic-bezier(0.2, 0.85, 0.2, 1);
  }

  ::view-transition-old(cf-media),
  ::view-transition-new(cf-media) {
    height: 100%;
    object-fit: cover;
    overflow: clip;
  }

  /* Destination names: the product page's first-paint photo and title. */
  .pdp-main-media img.cf-vt-media { view-transition-name: cf-media; }
  .pdp-info .cf-vt-title { view-transition-name: cf-title; }
  .topbar { view-transition-name: cf-topbar; }
  ::view-transition-group(cf-topbar) { animation-duration: 0s; }
}

@keyframes ux-vt-out {
  to { opacity: 0; }
}

@keyframes ux-vt-in {
  from { opacity: 0; translate: 0 10px; }
  to { opacity: 1; translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  :where(*) {
    scale: none !important;
    translate: none !important;
  }
  .mobile-nav:not([hidden]),
  .mobile-nav:not([hidden]) a {
    animation: none;
  }
}
