/* =========================================================
   HGS - MOTION SYSTEM
   ---------------------------------------------------------
   Reusable entrance-animation vocabulary for the whole site.

   HTML describes the choreography:

     data-anim="up|down|left|right|fade|scale|pop|zoom|settle|line|reveal"
     data-delay="1..8"          -> 80ms steps (60ms on small screens)
     data-speed="xfast|fast|slow|xslow"
     data-dist="sm|lg"

     data-anim-group            -> animate the direct children as a set
       data-anim-child="..."    -> animation per child (also "alt", "center")
       data-order="forward|reverse|center-out|edges-in|rows|diagonal"
       data-stagger="60"        -> ms between children

     data-anim-seq              -> reveal every unit inside as one composition
     data-anim-hero             -> a sequence that plays on page load
     data-anim-line             -> also animates the ::before connector line

   CSS/JS implement it centrally. JS adds `has-anim` to <html>; without
   JS (or with prefers-reduced-motion) nothing is ever hidden.
   ========================================================= */

:root {
    --anim-dur: 600ms;
    --anim-delay: 0ms;
    --anim-dist-y: 40px;
    --anim-dist-x: 44px;
    --anim-op: 1;
    --anim-ease: cubic-bezier(0.22, 0.68, 0.32, 1);
    --anim-ease-soft: cubic-bezier(0.25, 0.85, 0.35, 1);
}

/* ---------- speed / distance modifiers ---------- */
[data-speed="xfast"] { --anim-dur: 320ms; }
[data-speed="fast"]  { --anim-dur: 430ms; }
[data-speed="slow"]  { --anim-dur: 780ms; }
[data-speed="xslow"] { --anim-dur: 1050ms; }

[data-dist="sm"] { --anim-dist-y: 22px; --anim-dist-x: 24px; }
[data-dist="lg"] { --anim-dist-y: 56px; --anim-dist-x: 64px; }

/* ---------- delay scale ---------- */
[data-delay="1"] { --anim-delay: 80ms; }
[data-delay="2"] { --anim-delay: 160ms; }
[data-delay="3"] { --anim-delay: 240ms; }
[data-delay="4"] { --anim-delay: 320ms; }
[data-delay="5"] { --anim-delay: 400ms; }
[data-delay="6"] { --anim-delay: 480ms; }
[data-delay="7"] { --anim-delay: 560ms; }
[data-delay="8"] { --anim-delay: 640ms; }

/* Text that is not fully opaque by design keeps its own end value */
html.has-anim .hero p[data-anim],
html.has-anim .hero-text[data-anim],
html.has-anim .location-hero p[data-anim] { --anim-op: 0.9; }

/* =========================================================
   PRE-REVEAL STATE  (only ever active once JS is running)
   ========================================================= */
html.has-anim [data-anim]:not(.anim-in),
html.has-anim [data-anim-group]:not(.anim-ready) > * {
    opacity: 0;
}

/* Hero backgrounds must not delay the largest paint: they only settle. */
html.has-anim [data-anim="settle"]:not(.anim-in) {
    opacity: 1;
    transform: scale(1.06);
}

/* Scaling hero media must never create a horizontal scrollbar */
html.has-anim .hero,
html.has-anim .location-hero { overflow: hidden; }

html.has-anim [data-anim="line"] { transform-origin: center; }
html.has-anim [data-anim-line]::before { transform-origin: left center; }
html.has-anim [data-anim-line]:not(.anim-in)::before { transform: scaleX(0); }

/* =========================================================
   REVEAL
   fill-mode `backwards` keeps the from-frame during the delay and
   hands the element back to its own styles afterwards, so existing
   :hover transforms keep working untouched.
   ========================================================= */
html.has-anim [data-anim].anim-in {
    animation-duration: var(--anim-dur);
    animation-delay: var(--anim-delay);
    animation-timing-function: var(--anim-ease);
    animation-fill-mode: backwards;
}

html.has-anim [data-anim="up"].anim-in     { animation-name: anim-up; }
html.has-anim [data-anim="down"].anim-in   { animation-name: anim-down; }
html.has-anim [data-anim="left"].anim-in   { animation-name: anim-left; }
html.has-anim [data-anim="right"].anim-in  { animation-name: anim-right; }
html.has-anim [data-anim="fade"].anim-in   { animation-name: anim-fade; }
html.has-anim [data-anim="scale"].anim-in  { animation-name: anim-scale; }
html.has-anim [data-anim="zoom"].anim-in   { animation-name: anim-zoom; }
html.has-anim [data-anim="line"].anim-in   { animation-name: anim-line; }

html.has-anim [data-anim="pop"].anim-in {
    animation-name: anim-pop;
    animation-timing-function: var(--anim-ease-soft);
}

html.has-anim [data-anim="reveal"].anim-in {
    animation-name: anim-reveal;
    animation-timing-function: var(--anim-ease-soft);
}

html.has-anim [data-anim="settle"].anim-in {
    animation: anim-settle 1200ms var(--anim-ease-soft) var(--anim-delay) backwards;
}

/* the picture inside a masked reveal settles out of a soft zoom */
html.has-anim [data-anim="reveal"].anim-in img {
    animation: anim-settle calc(var(--anim-dur) + 320ms) var(--anim-ease-soft) var(--anim-delay) backwards;
}

html.has-anim [data-anim-line].anim-in::before {
    animation: anim-lineX 720ms var(--anim-ease) 60ms backwards;
}

/* ---------- keyframes ---------- */
@keyframes anim-up {
    from { opacity: 0; transform: translate3d(0, var(--anim-dist-y), 0); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-down {
    from { opacity: 0; transform: translate3d(0, calc(var(--anim-dist-y) * -0.45), 0); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-left {
    from { opacity: 0; transform: translate3d(calc(var(--anim-dist-x) * -1), 0, 0); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-right {
    from { opacity: 0; transform: translate3d(var(--anim-dist-x), 0, 0); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-fade {
    from { opacity: 0; }
    to   { opacity: var(--anim-op); }
}

@keyframes anim-scale {
    from { opacity: 0; transform: translate3d(0, 14px, 0) scale(0.965); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-pop {
    from { opacity: 0; transform: scale(0.88); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-zoom {
    from { opacity: 0; transform: scale(1.05); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-settle {
    from { transform: scale(1.06); }
    to   { transform: none; }
}

@keyframes anim-line {
    from { opacity: 0; transform: scaleX(0); }
    to   { opacity: var(--anim-op); transform: none; }
}

@keyframes anim-lineX {
    from { transform: scaleX(0); }
    to   { transform: none; }
}

@keyframes anim-reveal {
    from { opacity: 0; clip-path: inset(0 0 100% 0); }
    to   { opacity: var(--anim-op); clip-path: inset(0 0 0 0); }
}

/* =========================================================
   HEADER - subtle depth once the page is scrolled.
   Navigation itself is never delayed or hidden.
   ========================================================= */
.anim-scroll-sentinel {
    position: absolute;
    top: 0;
    left: 0;
    width: 1px;
    height: 48px;
    pointer-events: none;
    opacity: 0;
}

.header {
    transition: box-shadow 0.28s ease, border-bottom-color 0.28s ease;
}

html.is-scrolled .header {
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.07);
    border-bottom-color: transparent;
}

/* Mobile menu: entries settle in behind the sliding panel */
.mobile-menu__nav > * {
    opacity: 0;
    transform: translate3d(16px, 0, 0);
    transition: opacity 0.26s ease, transform 0.26s var(--anim-ease);
}

.mobile-menu.is-open .mobile-menu__nav > * {
    opacity: 1;
    transform: none;
}

.mobile-menu.is-open .mobile-menu__nav > :nth-child(1) { transition-delay: 0.10s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(2) { transition-delay: 0.14s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(3) { transition-delay: 0.18s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(4) { transition-delay: 0.22s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(5) { transition-delay: 0.26s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(6) { transition-delay: 0.30s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(7) { transition-delay: 0.34s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(8) { transition-delay: 0.38s; }
.mobile-menu.is-open .mobile-menu__nav > :nth-child(9) { transition-delay: 0.42s; }

/* =========================================================
   MOBILE - shorter travel, no horizontal crossing.
   Stacked layouts read best when everything rises in order.
   ========================================================= */
/* Every two-column layout in this project has collapsed by 1024px, so
   opposing horizontal reveals turn into a natural vertical order there. */
@media (max-width: 1024px) {
    html.has-anim [data-anim="left"].anim-in,
    html.has-anim [data-anim="right"].anim-in { animation-name: anim-up; }
}

@media (max-width: 768px) {
    :root {
        --anim-dist-y: 26px;
        --anim-dist-x: 26px;
    }

    [data-dist="lg"] { --anim-dist-y: 34px; --anim-dist-x: 34px; }

    [data-delay="1"] { --anim-delay: 60ms; }
    [data-delay="2"] { --anim-delay: 120ms; }
    [data-delay="3"] { --anim-delay: 180ms; }
    [data-delay="4"] { --anim-delay: 240ms; }
    [data-delay="5"] { --anim-delay: 300ms; }
    [data-delay="6"] { --anim-delay: 340ms; }
    [data-delay="7"] { --anim-delay: 380ms; }
    [data-delay="8"] { --anim-delay: 420ms; }

    [data-speed="slow"]  { --anim-dur: 660ms; }
    [data-speed="xslow"] { --anim-dur: 800ms; }
}

/* =========================================================
   REDUCED MOTION - content is shown, motion is removed.
   ========================================================= */
@media (prefers-reduced-motion: reduce) {

    /* no reveal motion - but existing :hover transforms stay untouched */
    html.has-anim [data-anim],
    html.has-anim [data-anim]:not(.anim-in),
    html.has-anim [data-anim-group]:not(.anim-ready) > * {
        opacity: 1 !important;
        clip-path: none !important;
        animation: none !important;
    }

    html.has-anim [data-anim="settle"]:not(.anim-in) { transform: none !important; }

    html.has-anim [data-anim].anim-in img,
    html.has-anim [data-anim-line]::before,
    html.has-anim [data-anim-line].anim-in::before {
        animation: none !important;
        transform: none !important;
    }

    .header { transition: none; }

    .mobile-menu__nav > * {
        opacity: 1;
        transform: none;
        transition: none;
    }
}
