/* site.css — the ground the page stands on, and the hero.

   The page sits on one backdrop held to the screen (the silver-to-blue of
   the Stratasys "Everything Additive" artwork), so every section shows the
   same sheet and they meet without a seam. The hero is the brand's title
   over the sensor render (hero.js plays it); everything below it is next.css.

   Two hero layouts: wide screens (1200 px and up) set the title in two
   lines, right-aligned, over the render at the window's full width; narrower
   screens set it in three lines on the column's left edge, with the render
   hanging just under it, zoomed so its middle reads larger. */

:root {
    color-scheme: light;
    --ink: #14191C;
    --font-display: KoHo, "Avenir Next Condensed", system-ui, sans-serif;
    --font-body: Inter, -apple-system, "SF Pro Text", Helvetica, sans-serif;
    --backdrop-color: #B3BEC0; /* the backdrop's middle, where one flat colour is needed */
    --backdrop: linear-gradient(160deg, #9DA6A8 0%, #B3BEC0 35%, #CAD5D7 62%, #84C2DB 84%, #3D82B1 100%);

    /* The column's left edge (next.css: a 1440 px column, --gut inside it),
       which the hero's text lines up with. */
    --gut: clamp(20px, 5vw, 80px);
    --col: calc(max(0px, (100% - 1440px) / 2) + var(--gut)); /* 100%: the page's width where it is used (full-width boxes, or the screen for the pinned mark), without the scrollbar */

    /* The hero's caption is a folder: a tab on its left with a 45° shoulder,
       the strip right of it notched away. */
    --tab-w: 45%;
    --tab-h: 15px;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

html,
body {
    overflow-x: clip;
}

body {
    margin: 0;
    color: var(--ink);
    background: var(--backdrop-color) var(--backdrop) fixed;
}

h1, h2, h3, h4, h5, h6, p, figure {
    margin: 0;
}

/* Safari on iPhone and iPad ignores background-attachment: fixed (it paints
   the backdrop down the whole page, so it scrolls), so the backdrop is also
   painted on a layer pinned to the screen behind everything. */
body::before {
    content: "";
    position: fixed;
    inset: 0 0 auto;
    height: 100lvh; /* the screen with the browser's bars tucked away */
    z-index: -4; /* the bottom layer: under the pinned render, the frost and the logo */
    background: var(--backdrop-color) var(--backdrop) no-repeat;
    background-size: 100% 100%;
    pointer-events: none;
}

/* ---- Hero ---- */
.fl-hero {
    /* where its 1680 × 960 design sits in the window: centred across, at
       the top of the page (the logo 40 px in from the corner) */
    --hx: max(0px, (100% - 1680px) / 2);
    position: relative;
    height: 960px;
    overflow: clip;
}

/* The logo: its mark stays pinned to the screen where it sits at the top,
   while the wordmark beside it scrolls and fades away. It lies on the back
   layer, just over the backdrop, so the page passes over it. */
.fl-hero__logo {
    color: #000;
}

.fl-hero__mark,
.fl-hero__word {
    z-index: -1;
}

.fl-hero__mark {
    position: fixed;
    top: 40px;
    left: calc(var(--hx) + 40px);
    width: 43px;
    height: 40px;
}

/* Over the dark bands, which cover the mark, a white copy of it takes over
   (hero.js clips it to where a band is behind it). */
.fl-hero__mark--inv {
    z-index: 45;
    color: #FFFFFF;
    --dot-blue: #8FDCFF;
    pointer-events: none;
}

/* The mark's dot pulses slowly to blue and back. */
@keyframes dot-pulse {
    0%, 100% { fill: currentColor; }
    50% { fill: var(--dot-blue, #2FA8FF); }
}

@media (prefers-reduced-motion: no-preference) {
    .fl-mark-dot {
        animation: dot-pulse 3.2s ease-in-out infinite;
    }
}

/* The menu: a burger beside the pinned mark, there once the wordmark has
   scrolled away (next.js, html.fl-scrolled), opening a list of the
   page's parts under the mark. White over the dark bands (is-on-dark);
   on phones always the inverse of what is behind it. The burger and the
   list are each pinned to the screen themselves, so the burger can blend
   with the page. */
.fl-nav {
    --nav-top: 40px;
    --nav-left: calc(max(0px, (100% - 1680px) / 2) + 40px); /* the mark's corner (100%: the screen, where used) */
    --nav-h: 40px; /* the mark's height */
    --nav-in: 59px; /* past the mark (43 px) and a gap */
}

.fl-nav__btn {
    position: fixed;
    top: var(--nav-top);
    left: calc(var(--nav-left) + var(--nav-in));
    z-index: 50;
    display: grid;
    align-content: center;
    gap: 6px;
    width: var(--nav-h);
    height: var(--nav-h);
    margin: 0;
    padding: 0 7px;
    border: 0;
    background: none;
    color: var(--ink);
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transition: opacity .4s ease, visibility 0s .4s, color .2s;
}

html.fl-scrolled .fl-nav__btn,
.fl-nav__btn[aria-expanded="true"] {
    opacity: 1;
    visibility: visible;
    transition: opacity .4s ease, color .2s;
}

.fl-nav.is-on-dark .fl-nav__btn {
    color: #FFFFFF;
}

.fl-nav__btn span {
    display: block;
    height: 2px;
    background: currentColor;
    transition: transform .3s ease, opacity .2s ease;
}

/* open: the top and bottom bars cross */
.fl-nav__btn[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.fl-nav__btn[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.fl-nav__btn[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

.fl-nav__menu {
    position: fixed;
    top: calc(var(--nav-top) + var(--nav-h) + 16px);
    left: var(--nav-left);
    z-index: 50;
    margin: 0;
    padding: 8px 22px;
    white-space: nowrap;
    list-style: none;
    background: var(--ink);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: opacity .3s ease, transform .3s ease, visibility 0s .3s;
}

.fl-nav__btn[aria-expanded="true"] + .fl-nav__menu {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity .3s ease, transform .3s ease;
}

.fl-nav__menu li + li {
    border-top: 1px solid rgba(238, 243, 244, .16);
}

.fl-nav__menu a {
    display: block;
    padding: 14px 0;
    font: 500 13px/1.2 var(--font-display);
    letter-spacing: .14em;
    text-transform: uppercase; /* KoHo is always set in capitals */
    color: #EEF3F4;
    text-decoration: none;
    transition: color .2s;
}

.fl-nav__menu a small {
    font-size: inherit;
    color: rgba(238, 243, 244, .55);
}

.fl-nav__menu a:hover,
.fl-nav__menu a:focus-visible {
    color: #84C2DB;
}

/* Links land with the section's top clear of the mark. */
#fl [id] {
    scroll-margin-top: 100px;
}

@media (prefers-reduced-motion: no-preference) {
    html {
        scroll-behavior: smooth;
    }
}

/* The pinned layer: the sensor render and, over it, frosted glass, held
   to the screen behind the page. The glass is clear at the top and frosts
   over as the page starts to scroll (hero.js sets --frost, 0 to 1 over the
   first 400 px). The pin ends at the physical trigger's band: as the band
   rises the layer is cut off at its top edge, scroll-driven so the cut
   keeps exact step with the band (hero.js does it where that is not
   supported), and past it the layer is hidden. */
.fl-pin {
    position: fixed;
    inset: 0 0 auto;
    height: 100lvh;
    z-index: -3; /* over the backdrop, under the logo's mark and the page */
    pointer-events: none;
}

.fl-frost {
    position: absolute;
    inset: 0;
    opacity: var(--frost, 0);
    background: rgba(202, 213, 215, .45); /* the backdrop's pale silver */
    -webkit-backdrop-filter: blur(36px) saturate(1.15);
    backdrop-filter: blur(36px) saturate(1.15);
}

html:not(.fl-frosting) .fl-frost,
html.fl-unpinned .fl-pin {
    visibility: hidden; /* nothing to blur at the top, or past the pin's end (hero.js) */
}

@keyframes pin-end {
    from { clip-path: inset(0 0 0 0); }
    to { clip-path: inset(0 0 100% 0); }
}

/* From the band's top edge entering at the bottom of the screen to it
   reaching the top, the cut follows it up. */
@supports (animation-timeline: view()) {
    html {
        timeline-scope: --pin-end;
    }

    #trigger {
        view-timeline: --pin-end block;
    }

    .fl-pin {
        animation: pin-end linear both;
        animation-timeline: --pin-end;
        animation-range: cover 0% exit-crossing 0%;
    }
}

.fl-hero__word {
    position: absolute;
    top: 50px;
    left: calc(var(--hx) + 90px);
    width: 162px;
    height: 22px;
}

/* The sensor render (hero.js), the window's full width, centred down the
   hero, its sides fading into the backdrop. It is pinned to the screen
   where it sits at the top (in .fl-pin, which is the screen), so the
   page scrolls up over it, behind the frost. */
.fl-hero__video {
    position: absolute;
    top: 480px; /* the middle of the 960 px hero */
    left: 0;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    translate: 0 -50%;
    object-fit: contain;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 18%, #000 82%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 18%, #000 82%, transparent);
    transition: opacity .8s ease, scale .8s ease, filter .8s ease;
}

/* After its hold on the ring the render goes before it plays again
   (hero.js): it fades as it blurs and shrinks into the distance, as the
   team's cards arrive (next.css, demo-arrive) in reverse. Coming back it
   needs no fade, its first frames are empty. */
.fl-hero__video.is-fading {
    opacity: 0;
    scale: .8;
    filter: blur(12px);
}

.fl-hero__video:not(.is-fading) {
    transition-duration: 0s;
}

/* The title, in ink: its letters are filled with the backdrop itself (held
   to the screen by hero.js, --ink-x/y/w/h) and set to "difference", so over
   the bare backdrop they cancel to black, and wherever the render passes
   under them they turn to its difference, shifting as it plays. */
.fl-hero__title {
    position: absolute;
    top: 287px;
    right: calc(50% - 413px);
    font: 700 101.33px/1 var(--font-display);
    letter-spacing: -.03em;
    text-align: right;
    text-transform: uppercase;
    white-space: nowrap;
    color: transparent;
    background: var(--backdrop-color) var(--backdrop) no-repeat;
    background-size: var(--ink-w, 100vw) var(--ink-h, 100vh);
    background-position: var(--ink-x, 0) var(--ink-y, 0);
    -webkit-background-clip: text;
    background-clip: text;
    mix-blend-mode: difference;
}

.fl-hero__title span:last-child {
    display: block;
}

/* A line under the logo's wordmark, small, light and white, on its left
   edge. */
.fl-hero__kicker {
    position: absolute;
    top: 82px;
    left: calc(var(--hx) + 90px);
    font: 300 8px/1 var(--font-body);
    letter-spacing: .24em;
    text-transform: uppercase;
    color: #FFFFFF;
    white-space: nowrap;
}

/* The caption: an ink folder hung under "Sensing", its left edge on the
   column's. hero.js brings it up as the render's ring closes. */
.fl-hero__caption {
    position: absolute;
    top: 594px;
    left: var(--col);
}

.fl-hero__box {
    width: 432px;
    padding: 34px 16px 20px 27px;
    background: var(--ink);
    clip-path: polygon(0 0, var(--tab-w) 0, calc(var(--tab-w) + var(--tab-h)) var(--tab-h),
                       100% var(--tab-h), 100% 100%, 0 100%);
}

.fl-hero__box p {
    font: 500 15px/22.5px var(--font-body);
    color: #F4F4F2;
}

/* Hidden from the first paint until the ring brings it up (hero.js); in the
   narrow hero it leaves again with the render as that fades out. */
@keyframes caption-up {
    from { opacity: 0; transform: translateY(24px); }
    to { opacity: 1; transform: none; }
}

@keyframes caption-out {
    from { opacity: 1; }
    to { opacity: 0; }
}

html:not(.hero-caption-in):not(.hero-caption-out) .fl-hero__box {
    visibility: hidden;
}

html.hero-caption-in .fl-hero__box {
    animation: caption-up 1.6s cubic-bezier(.2, .7, .3, 1) both;
}

html.hero-caption-out .fl-hero__box {
    animation: caption-out .8s ease both;
}

/* The page below starts 50 px under the render's frame: the hero runs on
   past the frame (it is centred in the 960 px hero), so the first section
   is drawn up by the difference. */
#fl > .fl-sec:first-child {
    margin-top: min(0px, 28.125% - 480px); /* 28.125%: half the frame's height, as a share of the page's width */
    padding-top: 50px;
}

/* The narrow hero: the title on the column's left edge in three lines, the
   render 1.6 times the window's width, its ring crossing "Mechanical" (no
   taller than the 514 px the design leaves it), the caption over the
   ring's lower left-hand corner, and the hero ending with the render's
   frame, so the next section follows straight on. */
@media (max-width: 1199.98px) {
    .fl-hero {
        --film: min(160vw, 913.8px);
        /* the render's frame is raised so its ring (whose top is 16% down
           the frame) crosses the middle of "Mechanical" (80 px above where
           it would start under "Sensing"); the hero still ends with the
           frame */
        --lift: calc(var(--film) * 9 / 16 * .16 + 80px); /* the title sits 16 px lower than its old 99 px, under the line beneath the logo, and the logo 16 px higher: they cancel */
        height: calc(244px + var(--film) * 9 / 16 - var(--lift));
    }

    .fl-hero__mark {
        top: 24px;
        left: var(--col);
        width: 26px;
        height: 25px;
    }

    .fl-nav {
        --nav-top: 24px;
        --nav-left: var(--col);
        --nav-h: 25px;
        --nav-in: 34px; /* where the wordmark started */
    }

    /* white, set to "difference": the inverse of whatever passes behind */
    .fl-nav__btn {
        top: calc(var(--nav-top) - 3.5px); /* centred on the mark */
        width: 32px;
        height: 32px;
        padding: 0 6px;
        gap: 5px;
        color: #FFFFFF;
        mix-blend-mode: difference;
    }

    .fl-nav__btn[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    .fl-nav__btn[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

    .fl-nav__menu {
        top: calc(var(--nav-top) + var(--nav-h) + 14px);
        padding-inline: 18px;
    }

    .fl-nav__menu a {
        font-size: 12px;
        letter-spacing: .1em;
    }

    #fl [id] {
        scroll-margin-top: 72px;
    }

    .fl-hero__word {
        top: 28px;
        left: calc(var(--col) + 34px);
        width: 110px;
        height: 15px;
    }

    .fl-hero__video {
        top: calc(244px - var(--lift));
        left: 50%;
        width: var(--film);
        translate: -50% 0;
    }

    .fl-hero__title {
        top: 99px;
        right: auto;
        left: var(--col);
        font-size: 43.4px;
        text-align: left;
    }

    .fl-hero__title span {
        display: block;
    }

    .fl-hero__kicker {
        top: 51px;
        left: calc(var(--col) + 34px);
        letter-spacing: .2em;
    }

    .fl-hero__caption {
        top: calc(262px + var(--film) * 9 / 16 * .62 - var(--lift));
    }

    .fl-hero__box {
        width: 248px;
        padding: 27px 12px 12px;
    }

    .fl-hero__box p {
        font-size: 14.25px;
        line-height: 18px;
    }

    #fl > .fl-sec:first-child {
        margin-top: 0; /* this hero already ends with the frame */
    }
}

/* As the hero scrolls away its title and caption drift up and fade, and
   the wordmark leaves first, handing over to the pinned mark. These run off
   the scroll position itself, so they stay smooth. */
@supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
        @keyframes hero-away {
            to { transform: translateY(-240px); opacity: 0; }
        }

        @keyframes wordmark-away {
            to { transform: translateY(-40px); opacity: 0; }
        }

        .fl-hero__title,
        .fl-hero__caption {
            animation: hero-away linear both;
            animation-timeline: scroll(root);
            animation-range: 0 800px;
        }

        .fl-hero__word,
        .fl-hero__kicker {
            animation: wordmark-away linear both;
            animation-timeline: scroll(root);
            animation-range: 0 400px;
        }
    }
}
