/* One motion language for the whole site: soft and short, transform and opacity only, so nothing shifts. This file
   loads before the theme; entrances are animations because the theme sets its own transition on .card-product and would
   override a transition here */
:root {
    --motion-ease: cubic-bezier(.2, .7, .2, 1);
    --motion-fast: .2s;
    --motion-base: .45s;
    --motion-slow: .7s;
    --motion-rise: 14px;
}

/* Page transitions only where the move means something: the slide on mobile (below) and the tab bar pill. Any other
   page swaps at once: a cross-fade read as a blink, and a product photo flying to its page half faded before the large
   photo had loaded. Browsers without support just load */
@view-transition {
    navigation: auto;
}
::view-transition-group(*) {
    animation-duration: .4s;
    animation-timing-function: var(--motion-ease);
}
/* Hidden rather than unanimated: two full-opacity snapshots are added up (plus-lighter) and flash white */
::view-transition-old(root) {
    display: none;
}
::view-transition-new(root) {
    animation: none;
}
/* Below every named part: Chrome sometimes drew the sliding page over the header, which then seemed to slide along */
::view-transition-group(root) {
    z-index: -1;
}
/* The header switches at once: on the home page it's transparent and taller, in the webshop narrower, and cross-fading
   showed two logos. Identical headers simply stay still */
.site-header {
    view-transition-name: site-header;
}
::view-transition-group(site-header),
::view-transition-new(site-header) {
    animation: none;
}
::view-transition-old(site-header) {
    display: none;
}
/* Customer area tab bar: the bar stays put and its icons cross-fade, while the active tab's pill travels to the new
   tab. A step forward or back slides the page, like an app (types: see meta.php). Desktop has no tab bar */
.app-tabbar {
    view-transition-name: app-tabbar;
}
.app-tabbar-item.is-active .app-tabbar-indicator {
    view-transition-name: app-tabbar-indicator;
}
/* In step with the page slide; drawn above the bar, so it multiplies and the icons show through as on the page */
::view-transition-group(app-tabbar-indicator) {
    animation-duration: var(--motion-base);
    mix-blend-mode: multiply;
}
/* From a page without an active tab it opens as on a tap */
::view-transition-new(app-tabbar-indicator):only-child {
    animation: app-tabbar-indicator-in var(--motion-base) var(--motion-ease) both;
}
/* Link in an open sheet: unnamed, sheet and backdrop were part of the old page, under the tab bar */
.app-sheet:is(.showing, .show) {
    view-transition-name: app-sheet;
}
.app-sheet:is(.showing, .show) ~ .offcanvas-backdrop {
    view-transition-name: app-sheet-backdrop;
}
::view-transition-old(app-sheet) {
    animation: app-sheet-out .35s var(--motion-ease) both;
}
/* Chrome copies the backdrop's blur onto its group: once the backdrop had faded, it blurred the whole page until the
   slide ended */
::view-transition-group(app-sheet-backdrop) {
    backdrop-filter: none;
}
@media (max-width: 991.98px) {
    html:active-view-transition-type(tab-forward)::view-transition-old(root) {
        display: block;
        animation: tab-out-left var(--motion-base) var(--motion-ease) both;
    }
    html:active-view-transition-type(tab-forward)::view-transition-new(root) {
        animation: tab-in-right var(--motion-base) var(--motion-ease) both;
    }
    html:active-view-transition-type(tab-back)::view-transition-old(root) {
        display: block;
        animation: tab-out-right var(--motion-base) var(--motion-ease) both;
    }
    html:active-view-transition-type(tab-back)::view-transition-new(root) {
        animation: tab-in-left var(--motion-base) var(--motion-ease) both;
    }
}
@keyframes tab-out-left {
    to {
        opacity: 0;
        transform: translateX(-25%);
    }
}
@keyframes tab-in-right {
    from {
        opacity: 0;
        transform: translateX(25%);
    }
}
@keyframes tab-out-right {
    to {
        opacity: 0;
        transform: translateX(25%);
    }
}
@keyframes tab-in-left {
    from {
        opacity: 0;
        transform: translateX(-25%);
    }
}
@keyframes app-tabbar-indicator-in {
    from {
        opacity: 0;
        transform: scaleX(.4);
    }
}
@keyframes app-sheet-out {
    to {
        transform: translateY(100%);
    }
}
/* Dashboard intro, once per session (meta.php, app-intro.php). Until the plane is parsed the page shows the same
   green, so nothing of the dashboard flashes first */
.app-intro {
    display: none;
}
html.app-intro-on {
    background: #1e3e33;
}
html.app-intro-on .app-intro {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 2000;
}
.app-intro-plane {
    position: absolute;
    inset: 0;
    background: #1e3e33;
}
/* Centred like the app's start screen; the script then moves it from its top left corner */
.app-intro svg {
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(64vw, 320px);
    height: auto;
    aspect-ratio: 375 / 150;
    translate: -50% -50%;
    transform-origin: 0 0;
}
.app-intro svg[style] {
    translate: none;
}

/* Entrance on scroll; motion.js only sets this on what's still off screen at load. !important because
   .card-product.inactive in the webshop has its own opacity; the class is only there briefly */
.reveal-pending {
    opacity: 0 !important;
    transform: translateY(var(--motion-rise)) !important;
}
.reveal-in {
    animation: reveal-in var(--motion-slow) var(--motion-ease) var(--reveal-delay, 0s) backwards;
}
@keyframes reveal-in {
    from {
        opacity: 0;
        transform: translateY(var(--motion-rise));
    }
}

/* Photos fade in once loaded (motion.js) */
img.img-pending {
    opacity: 0;
}
img.img-loaded {
    animation: img-in var(--motion-base) var(--motion-ease);
}
@keyframes img-in {
    from {
        opacity: 0;
    }
}

/* Cards with their own page: the whole card is clickable and the photo zooms in gently. The card stays put: lifting and
   zooming at once looked restless. :hover on the column so the border doesn't flicker */
.card-media {
    overflow: hidden;
    border-radius: var(--fc-card-inner-border-radius) var(--fc-card-inner-border-radius) 0 0;
}
.card-product.card-link,
.card-product.card-link:hover {
    transition: transform var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease), border-color var(--motion-base) var(--motion-ease);
}
.card-link .card-media img,
.card-link .icon-arrow-right {
    transition: transform var(--motion-slow) var(--motion-ease);
}
/* Mouse only: on a phone :hover sticks after a tap */
@media (hover: hover) {
    .col:hover > .card-link .card-media img {
        transform: scale(1.04);
    }
    .col:hover > .card-link .icon-arrow-right {
        transform: translateX(3px);
    }
}
.card-link .stretched-link:focus-visible {
    outline: none;
}
.card-link:has(.stretched-link:focus-visible) {
    outline: 2px solid var(--fc-primary);
    outline-offset: 3px;
}

main :is(p, li, small, .breadcrumb-item) > a:not(.btn, .stretched-link, .nav-link),
footer li > a:not(.btn) {
    text-decoration: none;
    background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
    transition: background-size var(--motion-base) var(--motion-ease), color var(--motion-fast) ease;
}
main :is(p, li, small, .breadcrumb-item) > a:not(.btn, .stretched-link, .nav-link):is(:hover, :focus-visible),
footer li > a:not(.btn):is(:hover, :focus-visible) {
    background-size: 100% 1px;
}

/* The link focus ring moves gently outward; buttons have the theme's ring */
a:focus-visible {
    animation: focus-ring var(--motion-fast) var(--motion-ease);
}
@keyframes focus-ring {
    from {
        outline-offset: 0;
    }
}

/* Month bar on the product page: the months light up one by one */
.monthbar-grid .month-cell.is-active::before {
    transform-origin: left;
}
.monthbar-grid.bar-pending .month-cell.is-active::before {
    transform: scaleX(0);
}
.monthbar-grid.bar-pending .month-cell.is-active .month-label {
    color: inherit;
}
.monthbar-grid.bar-in .month-cell.is-active::before {
    transition: transform var(--motion-base) var(--motion-ease) calc(var(--month, 0) * 45ms);
}
.monthbar-grid.bar-in .month-cell.is-active .month-label {
    transition: color var(--motion-fast) ease calc(var(--month, 0) * 45ms + 120ms);
}

/* On paper everything as it should be, including what hasn't been in view yet */
@media print {
    .reveal-pending,
    img.img-pending {
        opacity: 1 !important;
        transform: none !important;
    }
    .monthbar-grid.bar-pending .month-cell.is-active::before {
        transform: none;
    }
    .monthbar-grid.bar-pending .month-cell.is-active .month-label {
        color: #fff;
    }
}

@media (prefers-reduced-motion: reduce) {
    @view-transition {
        navigation: none;
    }
    .card-product.card-link,
    .card-product.card-link:hover,
    .card-link .card-media img,
    .card-link .icon-arrow-right,
    main :is(p, li, small, .breadcrumb-item) > a:not(.btn, .stretched-link, .nav-link),
    footer li > a:not(.btn) {
        transition: none;
    }
    .col:hover > .card-product.card-link,
    .col:hover > .card-link .card-media img,
    .col:hover > .card-link .icon-arrow-right {
        transform: none;
    }
    a:focus-visible {
        animation: none;
    }
}
