/*
 * Scroll reveal, driven by the data-aos attributes the markup already carries.
 *
 * The legacy documents were authored against AOS and carry 2,267 `data-aos` attributes across the
 * 55 published pages - fade-up 1571, fade-down 374, fade-right 184, fade-left 136. The library
 * itself was dropped in the rebuild, correctly: it was a render-blocking third-party request from
 * unpkg.com, and main.js had said "AOS disabled" for months, so every one of those attributes was
 * already inert. This honours what the markup asks for instead of inventing a second motion
 * language on top of it.
 *
 * MINIMAL, AND MEANT LITERALLY: two properties, opacity and a small translate. No keyframes, no
 * loops, no parallax, nothing that runs after the element has arrived. An effect that keeps moving
 * is the thing that reads as a template.
 *
 * EVERY RULE IS SCOPED TO `.ely-motion`, which InlineScripts sets on <html> before first paint and
 * only when the browser has IntersectionObserver AND the visitor has not asked for reduced motion.
 * Without that class nothing here applies and every element is simply visible - which is what must
 * happen if the script is blocked, because otherwise most of the body copy on the site would be
 * hidden for good.
 */

.ely-motion [data-aos] {
    opacity: 0;
    /* Duration is set per element by ely-motion.js from the markup's own data-aos-duration. */
    transition:
        opacity var(--ely-aos-duration, 600ms) cubic-bezier(0.22, 0.61, 0.36, 1) var(--ely-aos-delay, 0ms),
        transform var(--ely-aos-duration, 600ms) cubic-bezier(0.22, 0.61, 0.36, 1) var(--ely-aos-delay, 0ms);
}

/*
 * The offsets are deliberately small. AOS ships 100px; at that distance a four-across row of cards
 * reads as sliding furniture. 18px is enough to be felt and not enough to be watched.
 */
.ely-motion [data-aos^="fade-up"]    { transform: translate3d(0, 18px, 0); }
.ely-motion [data-aos^="fade-down"]  { transform: translate3d(0, -18px, 0); }
.ely-motion [data-aos^="fade-right"] { transform: translate3d(-18px, 0, 0); }
.ely-motion [data-aos^="fade-left"]  { transform: translate3d(18px, 0, 0); }

/* Revealed, once. The class is added by the observer and never removed, so nothing re-animates
   when a visitor scrolls back up past something they have already read. */
.ely-motion [data-aos].ely-in {
    opacity: 1;
    transform: none;
}

/*
 * A belt to the script's braces. `.ely-motion` is only set when the visitor has NOT asked for
 * reduced motion, so this should be unreachable - but a preference can change after load, and the
 * cost of being wrong here is invisible content.
 */
@media (prefers-reduced-motion: reduce) {
    .ely-motion [data-aos] {
        opacity: 1;
        transform: none;
        transition: none;
    }
}


/* ------------------------------------------------------------------ chat: waiting for a reply */

/*
 * Three dots that actually move, in place of the literal "…" the reply bubble used to hold — which
 * a visitor could not tell apart from the assistant having answered with an ellipsis.
 *
 * NOT scoped to .ely-motion, unlike everything above it. That class gates rules that HIDE content,
 * and being wrong there costs the page. This only animates something already visible, so under
 * reduced motion the dots simply stop moving and the bubble still reads as a pause. The
 * visually-hidden "Thinking…" beside them is what a screen reader gets either way.
 */
.ely-typing {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 0;
}

.ely-typing span {
    width: 7px;
    height: 7px;
    border-radius: 999px;
    background: #7c51fb;
    opacity: 0.35;
    animation: ely-typing-dot 1.25s ease-in-out infinite;
}

.ely-typing span:nth-child(2) { animation-delay: 0.18s; }
.ely-typing span:nth-child(3) { animation-delay: 0.36s; }

@keyframes ely-typing-dot {
    0%, 60%, 100% { opacity: 0.28; transform: translateY(0); }
    30%           { opacity: 1;    transform: translateY(-3px); }
}

@media (prefers-reduced-motion: reduce) {
    .ely-typing span {
        animation: none;
        opacity: 0.55;
    }
}

/* The screen-reader label beside the dots. `vh` is the house visually-hidden class; this is a
   fallback for the chat page, which does not otherwise use it. */
.ely-typing .vh {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}


/* ------------------------------------------------------------------ chat: start again */

/*
 * The "New chat" control is an <a class="reload-btn"> carrying only a circular-arrow SVG, which
 * reads as "refresh the page". ely-chat.js appends this label beside the icon; the rule is here
 * rather than in the frozen sheet for the same reason as everything else in this file.
 */
.reload-btn .ely-newchat-label {
    margin-left: 6px;
    font-size: 13px;
    font-weight: 600;
    vertical-align: middle;
}

.reload-btn {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}


/* ------------------------------------------------------------------ chat: handed to a person */

/*
 * The bubble that says a colleague has taken the conversation over. It is not the assistant
 * speaking, so it should not look like the assistant speaking - a tinted note rather than a reply.
 */
li.ely-handover .ai-message-bx {
    background: rgba(124, 81, 251, 0.06);
    border-radius: 12px;
}

li.ely-handover .ai-message-content p {
    color: #524972;
    font-style: normal;
}
