/* ===========================================================================
   "Inside your Odoo": the apps Aimee works in, as three drifting rows.

   The mechanic is measured off orionix.framer.website's client band, which is
   the reference: three tracks, every one moving at 35 px/s, direction
   alternating per row, and the whole block under a soft radial mask so the
   items dissolve towards the edges instead of being cut. The content is ours:
   the official Odoo Community app icons (assets/odoo-icons), laid out as one
   SVG per row so a row is a single decode no matter how often it repeats.

   The track holds four identical copies and travels exactly one copy plus one
   gap, so the wrap lands on identical pixels: with T = 4S + 3g, moving from
   -(25% + g/4) to -(50% + g/2) is -(S + g) to -(2S + 2g).
   =========================================================================== */

.apps {
    position: relative;
    z-index: 1;
    /* A screen of its own, the way the hero has one: the band of apps is the
       page's second beat and it gets the same room. The rows sit centred in
       that height, so the air above and below comes from the screen rather
       than from padding, and the film still follows on the same white paper. */
    min-height: 100svh;
    display: grid;
    align-items: center;
    /* Even top and bottom: the floating nav already eats the first 95px, so a
       40px top made the composition sit high and leave the screen's last third
       empty. */
    padding: 96px 0 96px;
    background: #fff;
    overflow: hidden;
}

.apps__inner {
    display: grid;
    /* 1512: copy ~420, band ~800 — the reference's 520 / 838 split, on our
       own gutter. The band is inset on the right too; it does not bleed. */
    grid-template-columns: minmax(340px, 32%) 1fr;
    align-items: start;
    gap: 40px;
    padding: 0 var(--gutter);
}

/* ---- the copy ----------------------------------------------------------- */

/* Same header as the dial's capability entries one section down: the small
   uppercase outcome line, then the 64-design-pixel title. The dial sizes
   those from its 1728 frame, so the same sizes expressed in vw land on the
   identical rendered values. */
.apps__eyebrow {
    margin: 0 0 12px;
    font-size: clamp(9px, 0.694vw, 12px);
    line-height: 1.55;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #171717;
    white-space: nowrap;
}

.apps__title {
    max-width: 16ch;
    margin: 0;
    font-weight: 400;
    font-size: clamp(32px, 3.7037vw, 64px);
    line-height: 1;
    letter-spacing: -0.0075em;
    color: #212121;
    text-wrap: balance;
}

/* ---- the marquee -------------------------------------------------------- */

/* The block runs to the viewport's right edge; the mask, not a hard edge,
   is what ends it. */
.apps__rows {
    /* Airy like the reference, where one logo cell is roughly twice its
       artwork. */
    --gap: 116px;
    position: relative;
    display: flex;
    flex-direction: column;
    /* The band now stands in a full screen, so the three rows spread into it
       rather than huddling at 16px. */
    gap: 40px;
    overflow: hidden;
    /* Ends exactly at the viewport's right edge, so the mask's fade finishes
       on screen instead of the items being cut by it. */
    width: 100%;
    /* The reference's mask, measured off it: an ellipse exactly the size of
       the box, opaque to 37% of its radius and gone by 99%. It is what makes
       the middle row read strongest and the outer two sit back, and what
       dissolves the rows at the left and right instead of cutting them. */
    /* Two masks, intersected: the reference's ellipse, which is what dissolves
       the rows left and right, and a straight vertical fade so the top and
       bottom rows do not end on a line either. */
    -webkit-mask-image: radial-gradient(50% 88% at 50% 50%,
        #000 37.2%, rgba(0, 0, 0, 0) 99.2%),
        linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 18%, #000 82%, rgba(0, 0, 0, 0) 100%);
    -webkit-mask-composite: source-in;
    mask-image: radial-gradient(50% 88% at 50% 50%,
        #000 37.2%, rgba(0, 0, 0, 0) 99.2%),
        linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 18%, #000 82%, rgba(0, 0, 0, 0) 100%);
    mask-composite: intersect;
}

.apps__row {
    position: relative;
    height: 140px;
    flex: 0 0 auto;
}

.apps__track {
    display: flex;
    align-items: center;
    height: 100%;
    gap: var(--gap);
    width: max-content;
    animation: apps-drift var(--dur, 36s) linear infinite;
    animation-delay: var(--phase, 0s);
    /* Its own layer, moved in 3D: the browser slides a finished bitmap
       instead of re-rasterising 24 icons every frame. */
    will-change: transform;
    backface-visibility: hidden;
    transform: translate3d(0, 0, 0);
}

/* Rows 2 and 4 run the other way, as in the reference. */
.apps__row:nth-child(even) .apps__track {
    animation-direction: reverse;
}

/* Off screen it costs nothing: apps.js drops the flag when the section
   leaves the viewport. */
.apps:not(.is-running) .apps__track {
    animation-play-state: paused;
}

/* ---- one app ------------------------------------------------------------
   At rest the whole row is held back: the icons desaturated and faint, the
   names light grey, so the band reads as texture beside the headline. Under
   the pointer the app comes forward: its own Odoo colours and black type. */

.apps__chip {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: none;
    cursor: default;
}

.apps__chip img {
    display: block;
    width: 46px;
    height: 46px;
    /* Grey at rest, its own Odoo colours under the pointer. Kept dense rather
       than faint, because the band's mask dims it a second time. */
    filter: grayscale(1);
    opacity: 0.88;
    transition: filter 0.35s cubic-bezier(0.32, 0.72, 0, 1),
        opacity 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}

.apps__chip-name {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 500;
    font-size: 17px;
    line-height: 1;
    white-space: nowrap;
    color: #8e8c96;
    transition: color 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}

.apps__chip:hover img {
    filter: none;
    opacity: 1;
}

.apps__chip:hover .apps__chip-name {
    color: var(--ink);
}

/* A name drifting at 35 px/s cannot be read, let alone pointed at: the row
   it belongs to holds still while the pointer is on it. */
.apps__row:hover .apps__track {
    animation-play-state: paused;
}

@keyframes apps-drift {
    from { transform: translate3d(calc(-25% - var(--gap) / 4), 0, 0); }
    to { transform: translate3d(calc(-50% - var(--gap) / 2), 0, 0); }
}

/* ---- arrival ------------------------------------------------------------
   The reference band has no reveal at all, but every other section here does,
   so it would read as the one dead spot on the page. Kept light: the copy
   rises, the rows follow. apps.js sets `is-revealed` on first view. */

.apps__eyebrow,
.apps__title,
.apps__rows {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 700ms ease, transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}

.apps.is-revealed .apps__eyebrow,
.apps.is-revealed .apps__title,
.apps.is-revealed .apps__rows {
    opacity: 1;
    transform: none;
}

.apps.is-revealed .apps__title { transition-delay: 90ms; }
.apps.is-revealed .apps__rows { transition-delay: 180ms; }

/* The list the marquee is a decoration of: read by screen readers, never
   painted. The rows themselves are aria-hidden. */
.apps__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

@media (prefers-reduced-motion: reduce) {
    .apps__track {
        animation: none;
        transform: translate3d(calc(-25% - var(--gap) / 4), 0, 0);
    }

    .apps__eyebrow,
    .apps__title,
    .apps__rows {
        transform: none;
        transition-duration: 200ms;
        transition-delay: 0ms;
    }
}

/* ---- narrow screens: copy over the rows --------------------------------- */

@media (max-width: 900px) {
    .apps {
        /* stacked: as tall as its content, not as the screen */
        min-height: 0;
        padding: 72px 0 152px;
    }

    .apps__inner {
        grid-template-columns: 1fr;
        gap: 36px;
        padding-left: 24px;
        padding-right: 24px;
    }

    .apps__title {
        max-width: none;
    }

    .apps__rows {
        --gap: 64px;
        width: calc(100% + 48px);
        margin-left: -24px;
        gap: 8px;
    }

    .apps__row {
        height: 76px;
    }

    .apps__chip {
        gap: 10px;
    }

    .apps__chip img {
        width: 34px;
        height: 34px;
    }

    .apps__chip-name {
        font-size: 14px;
    }
}
