/*
 * Motion layer
 *
 * Shared easing tokens and the small hover / press interactions that make the
 * interface feel worked through rather than static. Scroll reveals live in
 * js/components/motion.js.
 *
 * Rule of thumb: this file never animates `transform` on elements that GSAP
 * also animates (cards and buttons inside a reveal clear their inline
 * transforms when the reveal finishes, so the two cannot fight).
 */
:root {
  --motion-duration-fast: 0.18s;
  --motion-duration: 0.28s;
  --motion-duration-slow: 0.5s;
  --motion-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --motion-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --motion-lift: -0.4rem;
  --motion-shadow-soft: 0 1.2rem 2.8rem rgba(81, 15, 0, 0.14);
  --motion-shadow-lifted: 0 2rem 4rem rgba(81, 15, 0, 0.22);
}

/* Buttons and pills */

.button {
  transition:
    background-color var(--motion-duration) var(--motion-ease),
    color var(--motion-duration) var(--motion-ease),
    border-color var(--motion-duration) var(--motion-ease),
    transform var(--motion-duration-fast) var(--motion-ease);
}

.button:hover {
  box-shadow: var(--motion-shadow-soft);
  transform: translateY(var(--motion-lift));
}

.button:active {
  transform: translateY(0) scale(0.985);
  box-shadow: none;
  transition-duration: var(--motion-duration-fast);
}

.button-primary:hover {
  background-color: var(--theme-color-cluster-card-background);
}

.button-secondary:hover,
.button-accent:hover {
  background-color: var(--theme-color-light-brown);
}

/* The menu keeps its own, quieter version: no lift, just a warm tint. */
.header .menu-item .button:hover {
  transform: none;
  box-shadow: none;
  background-color: var(--theme-color-secondary);
}

.header .menu-item .button.button-secondary:hover {
  background-color: var(--theme-color-light-brown);
}

.button .button-image {
  transition: transform var(--motion-duration) var(--motion-ease);
}

/* Cards */

.card {
  transition: transform var(--motion-duration-slow) var(--motion-ease);
}

a.card:hover {
  transform: translateY(var(--motion-lift));
  box-shadow: var(--motion-shadow-lifted);
}

.card-figure-image {
  transition: transform 0.8s var(--motion-ease-out);
}

a.card:hover .card-figure-image {
  transform: scale(1.06);
}

.card-figure-caption {
  transition: opacity var(--motion-duration-slow) var(--motion-ease);
}

.card-heading,
.card-caption-text-large {
  transition: opacity var(--motion-duration) var(--motion-ease);
}

/* Links and list rows that already have a hover colour */

.menu-item-popover-menu-link-item a,
.menu-mobile-overlay-link,
.page-news-preview-title-text,
.rich-content-text a,
.content-text a {
  transition: color var(--motion-duration) var(--motion-ease);
}

.page-news-preview-list-item a,
.publication-item-preview,
.project-list-item,
.cluster-card {
  transition:
    background-color var(--motion-duration) var(--motion-ease),
    transform var(--motion-duration-slow) var(--motion-ease);
}

.page-news-preview-list-item a:hover,
.cluster-card:hover {
  transform: translateY(var(--motion-lift));
}

.page-news-preview-image {
  transition: transform 0.8s var(--motion-ease-out);
}

.page-news-preview-list-item a:hover .page-news-preview-image {
  transform: scale(1.05);
}

/* Filters, tags and pagination */

.filter-label,
.tag,
.pagination-button,
.page-numbers {
  transition:
    background-color var(--motion-duration) var(--motion-ease),
    color var(--motion-duration) var(--motion-ease),
    border-color var(--motion-duration) var(--motion-ease);
}

.pagination-button:not(.is-disabled):hover,
.page-numbers:hover {
  background-color: var(--theme-color-secondary);
}

/* Accordions */

.accordion-header,
.menu-mobile-overlay-accordion-item-header {
  transition: color var(--motion-duration) var(--motion-ease);
}

/* The news ticker headline */

.news-ticker a,
.news-item {
  transition: opacity var(--motion-duration) var(--motion-ease);
}

.news-ticker a:hover {
  opacity: 0.75;
}

/*
 * Page intro
 *
 * Runs in CSS, not in JavaScript: a deferred script starts after the browser
 * has already painted, which is why Safari showed the finished page first and
 * animated it a second time. These rules are in place before the first paint.
 *
 * `socion-intro` is set on <html> by a small inline script in the document
 * head and removed again by js/components/motion.js once the intro is over,
 * so nothing here can leave content stuck.
 */

/*
 * The frame fades in over a fixed overlay, never over the layout: a
 * transparent box the size of the light-box with a solid cream ring around it,
 * which fades away to reveal the dark red frame underneath.
 *
 * Two things this deliberately avoids: animating the light-box's own margins
 * (every line of text reflows mid-load) and animating the ring's edges (a
 * full-window repaint on every frame, which made the cursor stutter).
 * Opacity is the one property the compositor can do on its own.
 */
@keyframes socion-frame-draw {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
  }
}

@keyframes socion-fade-up {
  from {
    opacity: 0;
    transform: translateY(2.4rem);
  }
}

.socion-intro body::after {
  --intro-frame-top: var(--header-top-offset);

  content: '';
  position: fixed;
  z-index: 15;
  pointer-events: none;
  top: var(--intro-frame-top);
  right: var(--layout-lightbox-margin);
  bottom: var(--layout-lightbox-margin);
  left: var(--layout-lightbox-margin);
  border-radius: var(--layout-lightbox-border-radius);
  box-shadow: 0 0 0 100vmax var(--theme-color-secondary);
  animation: socion-frame-draw 0.85s var(--motion-ease-out) 0.1s both;
}

.socion-intro body.no-news-ticker::after {
  --intro-frame-top: var(--layout-lightbox-margin);
}

.socion-intro .news-ticker {
  animation: socion-fade-up 0.6s var(--motion-ease-out) 0.35s both;
}

/*
 * The hero is animated by js/pages/front-page.js; it only needs its starting
 * state here so it does not flash in first.
 */
.socion-intro .home-hero-pre-title,
.socion-intro .home-hero-title,
.socion-intro .home-hero-subtitle,
.socion-intro .home-hero-cta-button,
.socion-intro .hero-section-endorsement {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .socion-intro body::after {
    display: none;
  }

  .socion-intro .news-ticker {
    animation: none;
  }

  .socion-intro .home-hero-pre-title,
  .socion-intro .home-hero-title,
  .socion-intro .home-hero-subtitle,
  .socion-intro .home-hero-cta-button,
  .socion-intro .hero-section-endorsement {
    opacity: 1;
  }
}

/*
 * Elements the reveal helper is about to animate start hidden, but only once
 * the helper has confirmed it can run (it sets this class on <html>). Without
 * JavaScript, or with reduced motion, nothing is ever hidden.
 */
.socion-motion-ready [data-reveal]:not(.is-revealed) {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .button:hover,
  a.card:hover,
  .page-news-preview-list-item a:hover,
  .cluster-card:hover {
    transform: none;
  }

  a.card:hover .card-figure-image,
  .page-news-preview-list-item a:hover .page-news-preview-image {
    transform: none;
  }

  .socion-motion-ready [data-reveal]:not(.is-revealed) {
    opacity: 1;
  }
}
