/* ------------------------------------------------------------------
   Multi-app pager: Easy Beat / Jam Pad / Beat Machine
   Loaded after main.css + style.css, so it wins on shared selectors.
   ------------------------------------------------------------------ */

:root {
    /* how long one app stays on screen before it is swiped away */
    --slide-duration: 10s;
    /* how far a slide travels while it waits its turn */
    --drift-distance: 4%;
    --drift-distance-phone: 5%;
    /* how far a slide enters from / leaves to */
    --swipe-distance: 7%;
    --swipe-duration: 700ms;
    /* leaving keeps accelerating; entering coasts to a stop */
    --ease-in: cubic-bezier(.3, .05, .85, .3);
    --ease-out: cubic-bezier(.16, .84, .34, 1);
    /* accent of the blurred glow behind the phone, per app */
    --glow: #cb158e;
}

/* ---------- sizing (replaces the old resize.js) ---------- */

.logo {
    font-size: min(9vmin, 7.4vw);
    text-align: left;
}

/* when container queries are available, size the name off the text column
   instead of the viewport, so "Beat Machine" never outgrows it */
@supports (container-type: inline-size) {
    .intro {
        container-type: inline-size;
    }

    .logo {
        font-size: min(9vmin, 11.5cqi);
    }
}

.logo img {
    width: 1.1em;
    height: 1.1em;
    margin-right: 0.18em;
    -webkit-border-radius: 24%;
    -moz-border-radius: 24%;
    border-radius: 24%;
}

.info {
    font-size: min(4.6vmin, 30px);
    max-width: min(100%, 19em);
}

/* ---------- layout ---------- */

.intro {
    min-height: 0;
    -webkit-box-pack: justify;
    -webkit-justify-content: space-between;
    -moz-box-pack: justify;
    -ms-flex-pack: justify;
    justify-content: space-between;
    gap: 5vmin;
    min-width: 0;
}

/* Every stage stacks its slides in one grid cell, so the stage is as tall
   as its tallest app and nothing jumps while switching. */
.stage {
    display: grid;
    width: 100%;
    min-width: 0;
}

.stage>.slide {
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
    min-height: 0;
}

.names-stage,
.links-stage {
    -webkit-box-pack: start;
    justify-items: start;
    align-items: center;
}

.shots-stage {
    height: 100%;
    min-height: 0;
    /* one row that fills the column, so the mock-up is clamped to it
       instead of sizing the row to its own intrinsic height */
    grid-template-rows: minmax(0, 1fr);
}

.shots-stage .drift {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-align: center;
    -webkit-align-items: center;
    -ms-flex-align: center;
    align-items: center;
    -webkit-box-pack: center;
    -webkit-justify-content: center;
    -ms-flex-pack: center;
    justify-content: center;
}

/* ---------- slide transition ---------- */

/* Motion is one continuous gesture: a slide creeps towards the side it will
   leave on, speeds up over the last couple of seconds, and the swipe picks up
   from there and accelerates it off-stage. The incoming slide decelerates in. */

.slide {
    --dir: 1;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    -webkit-transform: translateX(calc(var(--dir) * var(--swipe-distance)));
    -ms-transform: translateX(calc(var(--dir) * var(--swipe-distance)));
    transform: translateX(calc(var(--dir) * var(--swipe-distance)));
    -webkit-transition: opacity var(--swipe-duration) ease, -webkit-transform var(--swipe-duration) var(--ease-in), visibility 0s linear var(--swipe-duration);
    transition: opacity var(--swipe-duration) ease, transform var(--swipe-duration) var(--ease-in), visibility 0s linear var(--swipe-duration);
}

.slide.is-active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    -webkit-transform: none;
    -ms-transform: none;
    transform: none;
    /* settle into place instead of racing past it */
    -webkit-transition-timing-function: ease, var(--ease-out), linear;
    transition-timing-function: ease, var(--ease-out), linear;
    -webkit-transition-delay: 0s, 0s, 0s;
    transition-delay: 0s, 0s, 0s;
}

.slide.is-leaving {
    -webkit-transform: translateX(calc(var(--dir) * var(--swipe-distance) * -1));
    -ms-transform: translateX(calc(var(--dir) * var(--swipe-distance) * -1));
    transform: translateX(calc(var(--dir) * var(--swipe-distance) * -1));
    -webkit-transition-timing-function: ease-in, var(--ease-in), linear;
    transition-timing-function: ease-in, var(--ease-in), linear;
}

/* The slow lean towards the side the slide will be swiped to.
   The auto-advance always moves forward, so the lean is always leftward. */
.drift {
    width: 100%;
    height: 100%;
    transition: none;
}

.names-stage .drift,
.links-stage .drift {
    width: auto;
}

.slide.is-active .drift {
    -webkit-animation: drift var(--slide-duration) linear both;
    -moz-animation: drift var(--slide-duration) linear both;
    animation: drift var(--slide-duration) linear both;
}

.shots-stage .slide.is-active .drift {
    -webkit-animation-name: drift-phone;
    -moz-animation-name: drift-phone;
    animation-name: drift-phone;
}

/* Dropping .is-active also drops the drift animation. pager.js pins the
   drift's current transform inline just before that, so the content carries
   on from where it actually was instead of snapping. */

/* Keyframe spacing does the accelerating: even creep for the first half,
   then a steepening ramp into the swipe. */
@-webkit-keyframes drift {
    0% {
        -webkit-transform: translateX(0);
    }

    25% {
        -webkit-transform: translateX(calc(var(--drift-distance) * -0.1146));
    }

    50% {
        -webkit-transform: translateX(calc(var(--drift-distance) * -0.2594));
    }

    75% {
        -webkit-transform: translateX(calc(var(--drift-distance) * -0.5115));
    }

    90% {
        -webkit-transform: translateX(calc(var(--drift-distance) * -0.7659));
    }

    100% {
        -webkit-transform: translateX(calc(var(--drift-distance) * -1.0));
    }
}

@keyframes drift {
    0% {
        transform: translateX(0);
    }

    25% {
        transform: translateX(calc(var(--drift-distance) * -0.1146));
    }

    50% {
        transform: translateX(calc(var(--drift-distance) * -0.2594));
    }

    75% {
        transform: translateX(calc(var(--drift-distance) * -0.5115));
    }

    90% {
        transform: translateX(calc(var(--drift-distance) * -0.7659));
    }

    100% {
        transform: translateX(calc(var(--drift-distance) * -1.0));
    }
}

@-webkit-keyframes drift-phone {
    0% {
        -webkit-transform: translateX(0) scale(1.0);
    }

    25% {
        -webkit-transform: translateX(calc(var(--drift-distance-phone) * -0.1146)) scale(0.99771);
    }

    50% {
        -webkit-transform: translateX(calc(var(--drift-distance-phone) * -0.2594)) scale(0.99481);
    }

    75% {
        -webkit-transform: translateX(calc(var(--drift-distance-phone) * -0.5115)) scale(0.98977);
    }

    90% {
        -webkit-transform: translateX(calc(var(--drift-distance-phone) * -0.7659)) scale(0.98468);
    }

    100% {
        -webkit-transform: translateX(calc(var(--drift-distance-phone) * -1.0)) scale(0.98);
    }
}

@keyframes drift-phone {
    0% {
        transform: translateX(0) scale(1.0);
    }

    25% {
        transform: translateX(calc(var(--drift-distance-phone) * -0.1146)) scale(0.99771);
    }

    50% {
        transform: translateX(calc(var(--drift-distance-phone) * -0.2594)) scale(0.99481);
    }

    75% {
        transform: translateX(calc(var(--drift-distance-phone) * -0.5115)) scale(0.98977);
    }

    90% {
        transform: translateX(calc(var(--drift-distance-phone) * -0.7659)) scale(0.98468);
    }

    100% {
        transform: translateX(calc(var(--drift-distance-phone) * -1.0)) scale(0.98);
    }
}

/* ---------- store badges ---------- */

.links {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    -webkit-box-align: center;
    -webkit-align-items: center;
    -ms-flex-align: center;
    align-items: center;
    gap: 2.2vmin;
}

.badge {
    display: block;
    line-height: 0;
}

.badge img {
    display: block;
    height: clamp(42px, 9vmin, 72px);
    width: auto;
}

.badge:hover img {
    -webkit-transform: translateY(-2px);
    -ms-transform: translateY(-2px);
    transform: translateY(-2px);
}

/* ---------- phone ---------- */

/* the frame image now carries the bezel, so drop the old background */
.screenshots {
    background-image: none;
    min-width: 0;
    /* let the column shrink past the mock-up's intrinsic height in the
       stacked layout, instead of pushing the page into a scroll */
    min-height: 0;
}

.screenshots::before {
    background: var(--glow);
    -webkit-transition: background-color 800ms ease;
    transition: background-color 800ms ease;
}

/* One composited mockup per app: the frame is stretched to that screenshot's
   own ratio, so every phone keeps the same screen width and rounded corners.
   Rebuild with tools/build-phones.py after replacing a screenshot. */
.phone {
    display: block;
    height: 100%;
    width: auto;
    max-width: 100%;
    max-height: 100%;
    -o-object-fit: contain;
    object-fit: contain;
    transition: none;
}

/* ---------- pager ---------- */

.pager {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    width: 100%;
    gap: 2.4vmin;
    transition: none;
}

.pager-item {
    -webkit-box-flex: 1;
    -webkit-flex: 1 1 0;
    -ms-flex: 1 1 0;
    flex: 1 1 0;
    min-width: 0;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    text-align: left;
    opacity: .45;
}

.pager-item:hover,
.pager-item.is-active {
    opacity: 1;
}

.pager-label {
    display: block;
    font-size: clamp(11px, 1.9vmin, 16px);
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: .8vmin;
}

.pager-track {
    display: block;
    width: 100%;
    height: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    background: #ffffff33;
    overflow: hidden;
}

.pager-fill {
    display: block;
    height: 100%;
    width: 0;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    background: #ffffff;
    /* when the item stops being active the animation goes away and the bar
       eases back to empty instead of blinking out */
    -webkit-transition: width var(--swipe-duration) ease;
    transition: width var(--swipe-duration) ease;
}

.pager-item.is-active .pager-fill {
    -webkit-animation: pager-fill var(--slide-duration) linear both;
    -moz-animation: pager-fill var(--slide-duration) linear both;
    animation: pager-fill var(--slide-duration) linear both;
}

@-webkit-keyframes pager-fill {
    from {
        width: 0;
    }

    to {
        width: 100%;
    }
}

@keyframes pager-fill {
    from {
        width: 0;
    }

    to {
        width: 100%;
    }
}

/* ---------- responsive ---------- */

@media (max-width: 768px) {

    .names-stage,
    .links-stage {
        justify-items: center;
    }

    /* stacked: the text block takes the room it needs, the phone gets the rest */
    .intro {
        gap: 4vmin;
        width: 100%;
        -webkit-box-flex: 0;
        -webkit-flex: 0 0 auto;
        -ms-flex: 0 0 auto;
        flex: 0 0 auto;
    }

    .screenshots {
        -webkit-box-flex: 1;
        -webkit-flex: 1 1 0;
        -ms-flex: 1 1 0;
        flex: 1 1 0;
        margin-top: 4vmin;
    }

    .pager-label {
        text-align: center;
    }
}

@media (prefers-reduced-motion: reduce) {

    .slide.is-active .drift {
        -webkit-animation: none;
        animation: none;
    }

    .slide,
    .slide.is-active,
    .slide.is-leaving {
        -webkit-transition: opacity 200ms linear, visibility 0s linear 200ms;
        transition: opacity 200ms linear, visibility 0s linear 200ms;
        -webkit-transform: none;
        -ms-transform: none;
        transform: none;
    }
}
