/**
 * SYNAIKIDO SoundArts - Navigation Menu Visual Theme
 * Site-specific visual styles for the navigation-menu component.
 */

navigation-menu {
    --decoration-color: var(--site-surface-decoration);
    --decoration-color-none: var(--site-surface-transparent);
    --container-decoration-color: var(--site-surface-glass-subtle);
    --overlay-background-color: var(--site-surface-overlay);

    --shadow: var(--site-shadow-glass);
    --shadow-subtle: var(--site-shadow-subtle);
    --notification-badge-bg: var(--site-color-notification-bg);
    --notification-badge-text: var(--site-color-notification-text);

    --entry-border-radius: var(--site-radius-pill);
    --menu-border-radius: var(--site-radius-panel);
    --submenu-border-radius: var(--menu-border-radius);

    --flex-gap: 3em;

    --inset-active-entry: -0.5em;
    --inset-active-entry-horizontal: -1em;
    --inset-active-entry-vertical: -1.25em;
    --inset-active-entry-horizontal-compact: -0.375em;
    --inset-active-entry-vertical-compact: var(--inset-active-entry-horizontal-compact);

    /* background: radial-gradient(circle, rgba(255, 255, 255, 0.5) 0%, rgba(220, 220, 220, 0.05) 52%, rgba(255, 255, 255, 0.5) 100%); */
    background-color: var(--site-surface-glass);
}

navigation-menu[initializing] {
    visibility: hidden;
    pointer-events: none;
}

/* No transition while the language-mismatch banner leaves or arrives. The
   prompt service republishes the navigation's offset every frame from the
   banner's rendered geometry, so the navigation is already told exactly where to
   be; a transition would lag behind those values and let the navigation drift
   into the banner it is making room for. Deliberately not an unconditional
   transition either: a client-side page navigation changes the nav's "top" - its
   position type switches between sticky and fixed, and sticky's own "top" always
   reports its declared threshold rather than its current flow-rendered position -
   so an always-on transition would visibly animate from that threshold value on
   every navigation, even when the nav was already in the right place. */

/*
 * Prerender/no-JavaScript fallback. The server may serialize the hydrated
 * navigation markup, but its responsive mode cannot run until the custom
 * element upgrades. Keep the native links usable without allowing the
 * full-size row to widen the mobile document in that interim state.
 */
body navigation-menu:not(:defined) {
    box-sizing: border-box;
    flex-direction: column;
    gap: 0.25rem;
    width: min(100%, 52rem);
    max-width: calc(100vw - 2rem);
    overflow: hidden;
    overflow: clip;
    padding: 0.25rem;
}

body navigation-menu:not(:defined) navigation-menu-header,
body navigation-menu:not(:defined) navigation-menu-body {
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    justify-content: center;
}

body navigation-menu:not(:defined) navigation-menu-body {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    overflow: hidden;
}

body navigation-menu:not(:defined) navigation-menu-body > * {
    min-width: 0;
    margin: 0;
}

body navigation-menu:not(:defined) navigation-menu-body > [has-submenu] {
    display: contents;
}

body navigation-menu:not(:defined) a {
    margin: 0;
    padding: 0.625rem 0.75rem;
}

body navigation-menu:not(:defined) navigation-menu-active,
body navigation-menu:not(:defined) navigation-menu-container-decoration,
body navigation-menu:not(:defined) navigation-menu-trigger,
body navigation-menu:not(:defined) navigation-submenu,
body navigation-menu:not(:defined) navigation-submenu-trigger,
body navigation-menu:not(:defined) navigation-menu-badge {
    display: none;
}

navigation-menu,
navigation-menu-container-decoration,
navigation-menu navigation-menu-body,
navigation-menu navigation-menu-header {
    border-radius: var(--menu-border-radius);
}

navigation-menu-container-decoration {
    background-color: var(--container-decoration-color);
    box-shadow: var(--shadow);
}

navigation-menu[full-size] navigation-menu-container-decoration {
    backdrop-filter: var(--site-backdrop-blur-strong);
    -webkit-backdrop-filter: var(--site-backdrop-blur-strong);
}

navigation-menu navigation-menu-body::before,
navigation-menu navigation-menu-header::before {
    border-radius: inherit;
    backdrop-filter: var(--site-backdrop-blur);
    -webkit-backdrop-filter: var(--site-backdrop-blur);
}

navigation-menu a,
navigation-menu div[entry][has-submenu]>.entry-link,
navigation-menu-active-overlay,
navigation-menu a navigation-menu-decoration {
    border-radius: var(--entry-border-radius);
}

navigation-menu a navigation-menu-decoration {
    border-color: var(--decoration-color) !important;
}

navigation-menu a {
    font-weight: bold;
}

navigation-menu [image-container] img[src$=".svg"] {
    filter: none;
    transition: filter 0.2s ease;
}

navigation-menu navigation-menu-trigger svg {
    stroke: currentColor;
}

body[color-scheme="dark"] navigation-menu [image-container] img[src$=".svg"] {
    filter: brightness(0) invert(1);
}

navigation-menu a:hover:not([active]),
navigation-menu div[entry][has-submenu]>a.entry-link:not([active]):hover,
navigation-menu div[entry][has-submenu]>span.entry-link:hover,
navigation-submenu>[entry]:hover:not([active]),
navigation-submenu-trigger:hover {
    background-color: var(--decoration-color);
}

navigation-menu-name,
navigation-menu-active-entry-name {
    font-weight: 900;
}

/* Keep the profile entry icon-only while retaining its localized active name. */
navigation-menu [entry="profile"] > navigation-menu-name,
navigation-menu [entry="profile"] > .entry-link > navigation-menu-name {
    display: none;
}

navigation-menu div[entry][has-submenu]>.entry-link {
    font-weight: bold;
}

navigation-menu-active-overlay {
    background-color: var(--overlay-background-color);
    box-shadow: var(--shadow);

    /* The transform transition is restated from the component's own stylesheet on
       purpose: `transition` is a shorthand, so declaring it here would otherwise
       drop the scale transition the component relies on. */
    transition:
        transform var(--timing-decoration) ease-in-out,
        opacity var(--timing-decoration) ease;
}

/* While a swipe is showing a page other than the one you are on, the overlay stops
   claiming to mark your place: it recedes almost to nothing, and comes back as the
   swipe returns to where it started. Not all the way to nothing, so the frame is
   still faintly there to return to rather than blinking out of existence.

   Left at a lower specificity than `navigation-menu[tiny] navigation-menu-active-overlay`,
   which hides the overlay outright, so a swipe in the tiny state cannot bring it back. */
navigation-menu-active-overlay[swiping-active-entry-name="origin-out-of-view"] {
    opacity: 0.1;
}

/* In the tiny state the overlay is hidden outright, so it cannot carry that signal
   and the names have to say it themselves: the page you are on stays full strength,
   anything you are only passing over reads as provisional. The name's own content is
   always the page you are on; a preview says so itself on the one occasion it is —
   a swipe carried a whole menu's worth of entries, arriving back where it began. */
navigation-menu[tiny] navigation-menu-active-entry-preview:not([shows-origin]) {
    color: var(--site-color-muted);
}

/* Drag-overlay navigation.
   The gesture has no hover or cursor affordance, so picking the marker up is the
   only moment that can confirm it; without a lift the drag is indistinguishable
   from a dead press. --drag-lift is the single resting scale that both drag
   states and the release keyframes settle to. */
navigation-menu-active-overlay[dragging] {
    --drag-lift: 1.06;
    /* Read by the component: how long to ease out of a wobble that a phase change
       interrupts, so a release cut short by re-attaching does not snap. 0 opts out. */
    --drag-phase-cut: 260;

    box-shadow: var(--shadow), 0 0.6em 1.6em rgb(0 0 0 / 0.28);
    transform: scale(var(--drag-lift));
}

/* Pulled free of an entry: a deeper shadow to read as further off the surface,
   and a soft-body overshoot so the overlay stretches and squashes like gum coming away
   and settling. Every step is relative to --drag-lift, so the animation ends
   exactly where the static rule leaves it and there is no pop when it finishes.
   This also covers the pickup, because a drag begins in the free phase: the
   marker is in hand and not yet attracted to anything. It replays on every
   detach after that, because the marker passes through "attracted" whenever it
   is caught, so the element stops matching this selector and matches again on
   the next release. */
navigation-menu-active-overlay[dragging="free"] {
    box-shadow: var(--shadow), 0 0.85em 2em rgb(0 0 0 / 0.32);
    animation: navigation-overlay-release 900ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Starts and ends at rest, so applying or dropping this animation never steps the
   transform. The stretch is reached quickly instead of being the opening frame,
   which keeps the gum feel without a pop on the way in. */
@keyframes navigation-overlay-release {
    0% {
        transform: scale(var(--drag-lift));
    }
    13% {
        transform: scale(calc(var(--drag-lift) * 1.075), calc(var(--drag-lift) * 0.885));
    }
    31% {
        transform: scale(calc(var(--drag-lift) * 0.952), calc(var(--drag-lift) * 1.078));
    }
    50% {
        transform: scale(calc(var(--drag-lift) * 1.042), calc(var(--drag-lift) * 0.968));
    }
    68% {
        transform: scale(calc(var(--drag-lift) * 0.984), calc(var(--drag-lift) * 1.026));
    }
    84% {
        transform: scale(calc(var(--drag-lift) * 1.013), calc(var(--drag-lift) * 0.991));
    }
    100% {
        transform: scale(var(--drag-lift));
    }
}

/* Travel bubble.
   A constant, much smaller wobble while the pointer is actually moving, carried
   by the MARKER rather than the overlay so it composes with the overlay's own
   lift and release animation instead of fighting it for the transform property.

   Its strength is not fixed: the component publishes --drag-speed (0..1, the
   pointer's speed against its reference) and --drag-angle (the direction of
   travel), and every deformation below is multiplied by the speed. A slow nudge
   therefore barely disturbs the marker while a fast throw stretches it hard,
   which is what makes it read as a soft body rather than a canned effect.

   The stretch is applied along the direction of travel by turning into that axis,
   scaling, and turning back — so dragging upward stretches the marker upward
   rather than always sideways. Perpendicular squash accompanies it, conserving
   rough area the way a real elastic body does.

   Because --drag-speed is already smoothed and falls to zero on its own, no
   amplitude ramp is needed: every keyframe below collapses to identity as speed
   decays, so the motion fades out with nothing to jump from. */
navigation-menu[dragging] navigation-menu-active {
    transform:
        rotate(var(--drag-angle, 0deg))
        scale(
            calc(1 + 0.085 * var(--drag-speed, 0)),
            calc(1 - 0.070 * var(--drag-speed, 0)))
        rotate(calc(-1 * var(--drag-angle, 0deg)));

    animation:
        navigation-marker-bubble 850ms ease-in-out infinite,
        navigation-marker-ripple 370ms ease-in-out infinite;
    animation-composition: add, add;
}

/* Setting off adds a one-shot kick over the ambient oscillation, itself scaled by
   how fast the pointer left. It has to be a separate animation rather than a
   louder opening to the oscillation, because the oscillation deliberately keeps
   its phase across a pause — fading the same wave back in gives no impulse.
   `animation-composition: add` is what lets the two share the transform, and lets
   both sit on top of the directional stretch above; without it the last animation
   in the list would simply win. Every keyframe set opens and closes on scale(1),
   identity under `add`, so layering or dropping one contributes nothing. */
navigation-menu[dragging][motion="moving"] navigation-menu-active {
    animation:
        navigation-marker-bubble 850ms ease-in-out infinite,
        navigation-marker-ripple 370ms ease-in-out infinite,
        navigation-marker-kick 460ms cubic-bezier(0.22, 1, 0.36, 1);
    animation-composition: add, add, add;
}

/* The body wobble: the slow, large mode. */
@keyframes navigation-marker-bubble {
    0%, 100% {
        transform: scale(1);
    }
    25% {
        transform: scale(
            calc(1 + 0.040 * var(--drag-speed, 0)),
            calc(1 - 0.034 * var(--drag-speed, 0)));
    }
    50% {
        transform: scale(
            calc(1 - 0.016 * var(--drag-speed, 0)),
            calc(1 + 0.019 * var(--drag-speed, 0)));
    }
    75% {
        transform: scale(
            calc(1 - 0.032 * var(--drag-speed, 0)),
            calc(1 + 0.038 * var(--drag-speed, 0)));
    }
}

/* A faster, smaller second mode riding on the first. Real soft bodies ring at
   more than one frequency, and a single sine reads as mechanical however big it
   gets; the two periods are deliberately not multiples of each other, so the
   combined shape keeps changing instead of repeating on a short loop. */
@keyframes navigation-marker-ripple {
    0%, 100% {
        transform: scale(1);
    }
    33% {
        transform: scale(
            calc(1 - 0.015 * var(--drag-speed, 0)),
            calc(1 + 0.017 * var(--drag-speed, 0)));
    }
    66% {
        transform: scale(
            calc(1 + 0.017 * var(--drag-speed, 0)),
            calc(1 - 0.014 * var(--drag-speed, 0)));
    }
}

@keyframes navigation-marker-kick {
    0% {
        transform: scale(1);
    }
    26% {
        transform: scale(
            calc(1 + 0.050 * var(--drag-speed, 0)),
            calc(1 - 0.042 * var(--drag-speed, 0)));
    }
    58% {
        transform: scale(
            calc(1 - 0.021 * var(--drag-speed, 0)),
            calc(1 + 0.025 * var(--drag-speed, 0)));
    }
    80% {
        transform: scale(
            calc(1 + 0.009 * var(--drag-speed, 0)),
            calc(1 - 0.008 * var(--drag-speed, 0)));
    }
    100% {
        transform: scale(1);
    }
}

@media (prefers-reduced-motion: reduce) {
    navigation-menu-active-overlay[dragging="free"],
    navigation-menu[dragging] navigation-menu-active,
    navigation-menu[dragging][motion="moving"] navigation-menu-active {
        animation: none;
        transform: none;
    }
}

navigation-menu[dragging] navigation-menu-body a:not([active]) navigation-menu-decoration {
    border-color: var(--decoration-color);
}

navigation-menu[navigation-menu-active-transitioning] navigation-menu-active-overlay {
    backdrop-filter: blur(0px);
    -webkit-backdrop-filter: blur(0px);
}

navigation-menu a:hover:not([active]) navigation-menu-decoration {
    border-color: var(--decoration-color);
    box-shadow: var(--shadow-subtle);
}

navigation-menu-active::before {
    border-radius: var(--site-radius-surface);
    background-color: currentColor;
}

navigation-submenu {
    border-radius: var(--submenu-border-radius);
    background-color: var(--container-decoration-color);
    box-shadow: none;
    backdrop-filter: var(--site-backdrop-blur);
    -webkit-backdrop-filter: var(--site-backdrop-blur);
}

[entry][open]>navigation-submenu {
    box-shadow: var(--shadow);
}

navigation-submenu-trigger {
    border-radius: 50%;
}

navigation-menu[compact] navigation-menu-container-decoration {
    backdrop-filter: var(--site-backdrop-blur);
    -webkit-backdrop-filter: var(--site-backdrop-blur);
}

navigation-menu[compact] div[entry][has-submenu] {
    border-radius: var(--menu-border-radius);
}

navigation-menu[compact] div[entry][has-submenu][open] {
    background-color: var(--container-decoration-color);
    box-shadow: var(--shadow);
}

navigation-menu[compact] navigation-submenu,
navigation-menu[compact] *[has-submenu][open] navigation-submenu {
    box-shadow: none;
}

navigation-menu[compact] navigation-submenu {
    background-color: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

navigation-menu navigation-menu-badge {
    background-color: var(--notification-badge-bg);
    color: var(--notification-badge-text);
    font-weight: 700;
    border-radius: var(--site-radius-round);
    box-shadow: var(--site-shadow-badge-ring);
}
