/*
 * Platform motion (docs/brand/MOTION-SYSTEM.md): seller area, account and error pages of the platform host.
 * Loaded after the component styles, never by storefront hosts. Forms post and reload the whole page, so work pages
 * stay sober: no page transition and no staggered entrance; only the seller home, which has no form, settles in.
 * The reduced-motion rule of app.css brings every animation and transition here down to nothing; the halos below are
 * also removed.
 */

/* A page reloaded after a form post appears at once: page transitions belong to storefronts (app.css). */
@view-transition {
    navigation: none;
}

@keyframes motion-rise {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
}

@keyframes motion-fade {
    from {
        opacity: 0;
    }
}

/* Page title: a short fade. Seller home: its blocks settle in one after the other (60 ms apart). */

.site-main > .page-header {
    animation: motion-fade var(--duration-panel) var(--ease-standard) backwards;
}

.home-grid > * {
    animation: motion-rise var(--duration-editorial) var(--ease-editorial) backwards;
}

.home-grid > :nth-child(2) {
    animation-delay: 60ms;
}

.home-grid > :nth-child(n + 3) {
    animation-delay: 120ms;
}

/* Messages that answer an action (saved, errors) appear without moving the layout. */
.alert,
.validation-message,
.field-error {
    animation: motion-fade var(--duration-panel) var(--ease-standard) backwards;
}

/* Main navigation: an underline grows from the left on hover and focus, and stays under the current section. */

.site-nav a:not(.btn),
.nav-button {
    position: relative;
}

.site-nav a:not(.btn)::after,
.nav-button::after {
    content: "";
    position: absolute;
    right: var(--space-1);
    bottom: 0.4rem;
    left: var(--space-1);
    height: 2px;
    border-radius: 1px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--duration-panel) var(--ease-standard);
}

.site-nav a:not(.btn):is(:hover, :focus-visible, [aria-current="page"])::after,
.nav-button:is(:hover, :focus-visible)::after {
    transform: scaleX(1);
}

/* Same specificity as the layout's link color, and loaded after it. */
.site-nav a:not(.btn)[aria-current="page"] {
    color: var(--color-brand);
}

/* The seller area's row (768 px and more): the same underline, under the current entry too; never under « + », a button. */
@media (min-width: 48rem) {
    .seller-nav-link:not(.seller-nav-new)::after {
        content: "";
        position: absolute;
        right: var(--space-2);
        bottom: 0.4rem;
        left: var(--space-2);
        height: 2px;
        border-radius: 1px;
        background: currentColor;
        transform: scaleX(0);
        transform-origin: left;
        transition: transform var(--duration-panel) var(--ease-standard);
    }

    .seller-nav-link:not(.seller-nav-new):is(:hover, :focus-visible, [aria-current="page"])::after {
        transform: scaleX(1);
    }
}

.nav-link {
    transition:
        background-color var(--duration-micro) var(--ease-standard),
        color var(--duration-micro) var(--ease-standard);
}

/* Buttons: a 1 px lift where hovering exists, the primary one lit by the brand, a press on touch and click. */

.btn {
    transition:
        background-color var(--duration-micro) var(--ease-standard),
        border-color var(--duration-micro) var(--ease-standard),
        box-shadow var(--duration-micro) var(--ease-standard),
        transform var(--duration-micro) var(--ease-standard);
}

@media (hover: hover) {
    .btn:not(.btn-link):hover {
        transform: translateY(-1px);
    }

    .btn-primary:hover {
        box-shadow: 0 6px 18px -8px var(--color-brand);
    }
}

/* Restates the press of app.css: the hover lift above is more specific and would otherwise cancel it. */
.btn:not(.btn-link):active {
    transform: scale(0.98);
}

/* The first step of an empty space calls once, after the page has settled. */

.empty-state .btn-primary {
    position: relative;
}

.empty-state .btn-primary::after {
    content: "";
    position: absolute;
    inset: -2px;
    border: 2px solid var(--color-brand);
    border-radius: inherit;
    opacity: 0;
    pointer-events: none;
    animation: motion-beckon calc(var(--duration-live) / 2) var(--ease-standard) var(--duration-editorial);
}

@keyframes motion-beckon {
    from {
        opacity: 0.7;
        transform: scale(1);
    }

    to {
        opacity: 0;
        transform: scale(1.25, 1.6);
    }
}

/* Fields: a soft brand halo joins the focus outline. */

.form-control {
    transition:
        border-color var(--duration-micro) var(--ease-standard),
        box-shadow var(--duration-micro) var(--ease-standard);
}

.form-control:focus-visible {
    box-shadow: 0 0 0 5px var(--color-brand-soft);
}

/* The storefront status card: « En ligne » breathes twice on arrival (under 5 s, WCAG 2.2.2). Offer rows stay still. */

.profile-status .status-badge-live .status-dot {
    position: relative;
}

.profile-status .status-badge-live .status-dot::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: currentColor;
    animation: motion-pulse var(--duration-live) var(--ease-standard) 2;
}

@keyframes motion-pulse {
    from {
        opacity: 0.5;
    }

    70%,
    to {
        opacity: 0;
        transform: scale(2.8);
    }
}

/* The seller home's storefront card: « Vitrine en ligne » breathes twice the same way. */

.storefront-state-live .storefront-dot::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--color-accent);
    animation: motion-pulse var(--duration-live) var(--ease-standard) 2;
}

@media (prefers-reduced-motion: reduce) {
    .storefront-state-live .storefront-dot::after,
    .profile-status .status-badge-live .status-dot::after,
    .empty-state .btn-primary::after {
        display: none;
    }
}
