/* next.css — the page below the hero: quiet and exact. The content sits
   straight on the backdrop in one centred column, divided by hairline rules
   rather than framed. KoHo is set large and tight for the headings (a word
   here and there filled white, a blue full stop), Inter carries the reading
   text, and colour stays out of the way: charcoal ink on the silver, white
   on the graphite bands, and a steel blue only as a point. Every title and
   block starts on the same left edge. The team keeps its cards. */

/* No word left alone on a last line, in any sentence or title (the last
   two words of each paragraph are also tied with a no-break space). Only
   the style is set, so a title held to one line (nowrap) stays so. */
.fl p,
.fl h2,
.fl h3,
.fl li,
.fl dd {
    text-wrap-style: pretty;
}

.fl {
    --k: #14191C;                    /* ink: cool charcoal, near black */
    --k2: rgba(20, 25, 28, .68);     /* secondary ink */
    --rule: rgba(20, 25, 28, .24);   /* hairlines */
    --p: #F3F6F7;                    /* paper, for the team cards: cool white */
    --r: #2E6F9C;                    /* steel blue, the backdrop's blue deepened, used as a point */
    --title: #FFFFFF;                /* section titles, white everywhere */
    /* every section title's size: up to 80 px, and on a phone as large as
       the longest single word, Mechanotendography (11.41 em), allows */
    --title-size: min(clamp(29px, 5.6vw, 80px), (100vw - 2 * var(--gut)) / 11.6);
    --gut: clamp(20px, 5vw, 80px);
    --gap: clamp(20px, 3vw, 48px);
    --display: var(--font-display);
    --body: var(--font-body);
    color: var(--k);
    font: 400 16px/1.6 var(--body);
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
}

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

.fl :where(h2, h3, h4, p, ul, ol, figure) {
    margin: 0;
}

.fl :where(ul, ol) {
    padding: 0;
    list-style: none;
}

.fl a {
    color: inherit;
}

/* ---- Sections: one column, set on the backdrop ---- */
.fl-sec {
    position: relative;
    container-type: inline-size; /* Mechanotendography is sized to the column */
    max-width: 1440px;
    margin: 0 auto;
    padding: clamp(72px, 11vw, 168px) var(--gut) 0;
}

.fl-head {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding-bottom: 12px;
    margin-bottom: clamp(32px, 5vw, 72px);
    border-bottom: 1px solid var(--rule);
    font: 500 12px/1 var(--display);
    text-transform: uppercase;
    letter-spacing: .2em;
}

/* A divider with no label keeps the line where a label would put it. */
.fl-head:empty {
    min-height: 25px; /* a 12 px label, its 12 px under it, the line */
}

/* Full-width bands in graphite (the backdrop's silver taken down to
   night), behind a section whose content stays in the column. Colours flip
   to the backdrop's pale silver, and the point lightens to sky blue. */
.fl-sec--dark {
    --k: #EEF3F4;
    --k2: rgba(238, 243, 244, .7);
    --rule: rgba(238, 243, 244, .24);
    --p: #11171A;
    --r: #84C2DB;
    color: var(--k);
    isolation: isolate;
    margin-top: clamp(72px, 11vw, 168px);
    padding-bottom: clamp(72px, 11vw, 168px);
}

.fl-sec--dark::before {
    content: "";
    position: absolute;
    inset: 0 calc(50% - 50vw);
    z-index: -1;
    background: #1B2327;
}

.fl-sec--dark + .fl-sec--dark {
    margin-top: 0;
}

/* ---- Type ---- */
.fl-mega {
    font: 700 var(--title-size)/.9 var(--display);
    text-transform: uppercase;
    letter-spacing: -.03em;
    color: var(--title);
}

.fl-mega .fl-out {
    -webkit-text-stroke-color: var(--title);
}

.fl-mega > span {
    display: block;
}

/* A title on one line, at the size of the method's name (.fl-word),
   running across both columns below it. */
.fl-mega--line > span {
    display: inline;
}

/* One line (14.2 em across) wherever the two columns sit side by side; on
   a phone, where they stack, it wraps at the common title size. */
@media (min-width: 861px) {
    .fl-mega--line {
        white-space: nowrap;
    }
}

/* A title kept to its two lines: on a phone it is set smaller rather than
   wrapped (its longer line is 15.2 em across). */
.fl-mega--two {
    font-size: min(var(--title-size), (100vw - 2 * var(--gut)) / 15.4);
    white-space: nowrap;
}

.fl-out {
    color: transparent;
    -webkit-text-stroke: clamp(1px, .12vw, 1.6px) var(--k);
}

/* The full stop after a title: the logo mark's dot, at its size on the
   screen (18.15 of the mark's 162 units: 4.8 px of its 43, 2.9 px of its
   26 on narrow screens) and in the blue it pulses to (site.css). */
.fl-dot {
    --mark-dot: 4.8px;
    display: inline-block;
    width: var(--mark-dot);
    height: var(--mark-dot);
    margin-left: .06em;
    border-radius: 50%;
    background: #2FA8FF;
}

.fl-sec--dark .fl-dot {
    background: #8FDCFF; /* as the white mark's dot over the dark bands */
}

@media (max-width: 1199.98px) {
    .fl-dot { --mark-dot: 2.9px; }
}

.fl-lede {
    font-size: clamp(16px, 1.25vw, 18px);
    line-height: 1.65;
    max-width: 36em;
}

.fl-say {
    font: 500 clamp(22px, 2.2vw, 32px)/1.2 var(--display);
    letter-spacing: .01em;
    text-transform: uppercase; /* KoHo is always set in capitals */
    max-width: 24em;
}

.fl-label,
.fl-sub {
    font: 500 11px/1.3 var(--display);
    text-transform: uppercase;
    letter-spacing: .22em;
    color: var(--k2);
}

.fl-sub {
    margin-bottom: 18px;
}

.fl-cols {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: var(--gap);
    margin-top: clamp(36px, 5vw, 80px);
    align-items: start;
}

.fl-cols > :first-child { grid-column: 1 / span 5; }
.fl-cols > :last-child { grid-column: 7 / span 6; }

@media (max-width: 860px) {
    .fl-cols > :first-child,
    .fl-cols > :last-child { grid-column: 1 / -1; }
}

/* ---- 02 Mechanical ---- */
.fl-mech-copy {
    margin-top: 0; /* the section's title, Mechanotendography (.fl-word), keeps its own gap above */
}

/* Figures: the picture, a hairline, a caption line. */
.fl-fig {
    display: flex;
    flex-direction: column;
    margin-top: clamp(48px, 7vw, 104px);
}

.fl-fig video {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 1518 / 590;
    background: var(--k);
}

/* Under it, a row of five close-ups from the webcams that film the
   training sessions: hands at work, wearing the band. */
.fl-cams {
    order: 1;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: clamp(6px, .8vw, 12px);
    margin-top: clamp(6px, .8vw, 12px);
}

.fl-cams video {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: var(--k);
}

.fl-fig__bar {
    order: 2;
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding-top: 10px;
    margin-top: 10px;
    border-top: 1px solid var(--rule);
    font: 500 11px/1 var(--display);
    text-transform: uppercase;
    letter-spacing: .2em;
    color: var(--k2);
}

.fl-rec::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 8px;
    border-radius: 50%;
    background: var(--r);
    translate: 0 -1px;
}

/* ---- 03 The physical trigger ---- */
/* Two blocks, top to bottom, on the 12-column grid and an even rhythm:
   the opening (title and its sentence on the left, the tendon clip on the
   right, tops level), then the chain from muscle to output. */
.fl-trig-open {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 32px var(--gap);
    align-items: start;
}

.fl-trig-copy { grid-column: 1 / span 5; }
.fl-trig-media { grid-column: 7 / span 6; }

/* "The physical" stays on one line, running into the empty column beside
   the copy if it must (it is 6.4 em across, a hair over five columns). */
.fl-trig-copy .fl-mega > span {
    white-space: nowrap;
}

.fl-trig-copy .fl-lede {
    margin-top: clamp(24px, 3vw, 40px);
}

.fl-trig-media video {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    background: #0E0E0E; /* the clip's own dark, on any ground */
}

@media (max-width: 860px) {
    .fl-trig-copy,
    .fl-trig-media { grid-column: 1 / -1; }
}

/* The method's description, a paragraph under the section's first,
   below its title, Mechanotendography (.fl-word). */
.fl-method {
    margin-top: clamp(20px, 2vw, 28px);
}

.fl-method .fl-lede {
    max-width: 34em;
}

.fl-chain {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--gap);
    margin-top: clamp(56px, 7vw, 104px);
    counter-reset: chain;
}

.fl-chain li {
    position: relative;
    padding-top: 14px;
    border-top: 1px solid var(--rule);
    counter-increment: chain;
}

.fl-chain li::before {
    content: counter(chain, decimal-leading-zero);
    display: block;
    margin-bottom: 14px;
    font: 500 11px/1 var(--display);
    letter-spacing: .2em;
    color: var(--r);
}

.fl-chain li:not(:last-child)::after {
    content: "→";
    position: absolute;
    top: 38px;
    right: calc(var(--gap) / -2);
    translate: 50% 0;
    font: 400 18px/1 var(--display);
    color: var(--k2);
}

.fl-chain b {
    display: block;
    font: 700 clamp(20px, 2vw, 30px)/1 var(--display);
    text-transform: uppercase;
}

.fl-chain small {
    display: block;
    margin-top: 6px;
    font-size: 14px;
    color: var(--k2);
}

@media (max-width: 760px) {
    .fl-chain { grid-template-columns: 1fr 1fr; row-gap: 28px; }
    .fl-chain li:nth-child(2)::after { display: none; }
}

/* Mechanotendography, the method's name and the section's title: one
   line, unbroken, left-aligned (the word is 11.41 em across in KoHo bold
   at this spacing). */
.fl-word {
    margin: 0 0 clamp(12px, 1.4vw, 20px);
    font: 700 var(--title-size)/.9 var(--display); /* as every section title */
    text-transform: uppercase;
    letter-spacing: -.03em;
    white-space: nowrap;
    color: var(--title);
}

.fl-word > span:nth-child(2) {
    color: transparent;
    -webkit-text-stroke: clamp(1px, .12vw, 1.6px) var(--title); /* as .fl-out */
}


/* ---- 04 Platform ---- */
/* The platform's two columns sit on the same 12-column grid as .fl-cols,
   so every second column starts on one line down the page. */
.fl-platform {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: clamp(48px, 6vw, 96px) var(--gap);
    margin-top: clamp(48px, 7vw, 104px);
}

.fl-platform > :first-child { grid-column: 1 / span 5; }
.fl-platform > :last-child { grid-column: 7 / span 6; }

@media (max-width: 960px) {
    .fl-platform > :first-child,
    .fl-platform > :last-child { grid-column: 1 / -1; }

    /* stacked, the sensor and its render come first, then the stack */
    .fl-platform > .fl-sensor { order: -1; }
}

/* Side by side, the two columns share three rows (a subgrid): their
   titles; the hardware and software layers beside the video; the data
   layer beside the specs. Every row of the stack is one height (--row),
   and the specs are that height too, so the data layer's rules and the
   specs' rules run on the same lines, and both columns end together. */
@media (min-width: 961px) {
    .fl-platform {
        --row: 56px;
        row-gap: 0;
    }

    .fl-plat-col {
        grid-row: span 3;
        display: grid;
        grid-template-rows: subgrid;
    }

    .fl-plat-body .fl-layer:last-child { margin-bottom: 0; }

    .fl-platform .fl-layer--data,
    .fl-platform .fl-specs {
        margin: 28px 0 0;
    }

    .fl-platform .fl-layer li {
        box-sizing: border-box;
        height: var(--row);
        padding-block: 0;
        align-items: center;
    }

    .fl-platform .fl-sensor__media {
        display: grid;
        align-items: center;
        padding: 0;
    }

    .fl-platform .fl-specs {
        box-sizing: border-box;
        height: calc(var(--row) + 2px);
        align-items: center;
        border-bottom: 1px solid var(--rule);
    }

    .fl-platform .fl-specs div { padding-top: 0; }
    .fl-platform .fl-specs span { display: block; }

    .fl-platform .fl-specs b { font-size: clamp(22px, 2vw, 30px); }
}

.fl-devices {
    margin-top: clamp(48px, 7vw, 104px);
}

/* A layer of the stack: its rows between hairlines, its name beside. */
.fl-layer {
    display: grid;
    grid-template-columns: 1fr 26px;
    gap: 12px;
    margin-bottom: 28px;
}

.fl-layer ol {
    border-top: 2px solid var(--k);
}

.fl-layer li {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 11px 0 10px;
    border-bottom: 1px solid var(--rule);
    font: 500 clamp(14px, 1.2vw, 16px)/1.25 var(--display);
    text-transform: uppercase;
    letter-spacing: .05em;
}

.fl-layer li::before {
    content: attr(data-n);
    min-width: 2.4em;
    font-size: 10px;
    letter-spacing: .1em;
    color: var(--k2);
}

.fl-layer > span {
    writing-mode: vertical-rl;
    rotate: 180deg;
    justify-self: center;
    align-self: start;
    padding-bottom: 12px;
    font: 500 10px/1 var(--display);
    letter-spacing: .3em;
    text-transform: uppercase;
    color: var(--k2);
}

.fl-layer--data li::before {
    color: var(--r);
}

.fl-stamp {
    margin-left: auto;
    font: 500 10px/1 var(--display);
    letter-spacing: .16em;
    color: var(--r);
}

.fl-stamp::before {
    content: "● ";
}

/* The sensor: the hero render, playing forward until the strip has
   settled (before it starts to curl) and then back, turning while it is
   still (a ping-pong file, video/sensor-pingpong.webm, zoomed in a little,
   with alpha), its sides fading out as the hero's do; then its sizes. */
.fl-sensor__media {
    padding: clamp(8px, 2vw, 24px) 0 clamp(16px, 3vw, 32px);
}

.fl-sensor__media video {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
}

.fl-specs {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin-top: 16px;
    border-top: 2px solid var(--k);
}

/* On a phone the four sizes stay in one row, set small. */
@media (max-width: 560px) {
    .fl-specs { gap: 10px; }
    .fl-specs div { padding-top: 10px; }
    .fl-specs b { font-size: 17px; }
    .fl-specs b small { font-size: .5em; }
    .fl-specs span { display: block; margin-top: 8px; font-size: 8px; line-height: 1.3; letter-spacing: .08em; white-space: nowrap; } /* "Total height" on one line */
    /* the stack's rows each on one line */
    .fl-layer li { gap: 10px; font-size: 12px; letter-spacing: .02em; white-space: nowrap; }
    .fl-stamp { letter-spacing: .08em; }
}

.fl-specs div {
    padding-top: 12px;
}

.fl-specs b {
    display: block;
    font: 700 clamp(26px, 3vw, 44px)/.9 var(--display);
    letter-spacing: -.02em;
}

.fl-specs b small {
    margin-left: .15em;
    font-size: .36em;
    font-weight: 500;
    text-transform: uppercase;
}

.fl-specs span {
    display: block;
    margin-top: 10px; /* clear of the figure above */
    font: 500 10px/1.3 var(--display);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--k2);
}

/* ---- 05 Devices ----
   Each device is a full-width row on the 12-column grid: its name on the
   left with its features under it, then its renders across the column
   (they are cut out, so they sit straight on the backdrop). */
.fl-device {
    position: relative;
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 0 var(--gap);
    padding-top: 16px;
    border-top: 2px solid var(--k);
}

.fl-device + .fl-device {
    margin-top: clamp(24px, 3vw, 40px);
}

.fl-device__meta { grid-column: 1 / span 5; position: relative; }
.fl-device ul { grid-column: 1 / span 5; margin-top: clamp(24px, 3vw, 40px); }
.fl-device__art { grid-column: 1 / -1; }

/* What a device is for (Fether Pro): a statement under its name, then its
   features, then its points, one above the other, down the left. */
.fl-device__lede { grid-column: 1 / span 5; }
.fl-device__points { grid-column: 1 / span 5; }

.fl-device__lede {
    margin-top: clamp(32px, 4vw, 56px);
}

.fl-device__points {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
    align-content: start;
    margin-top: clamp(28px, 3vw, 40px);
}

.fl-device__points dt {
    margin-bottom: 8px;
    font: 500 12px/1.2 var(--display);
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--r);
}

.fl-device__points dd {
    margin: 0;
    font-size: 15px;
    line-height: 1.55;
}

@media (max-width: 860px) {
    .fl-device__meta,
    .fl-device ul,
    .fl-device__lede,
    .fl-device__points { grid-column: 1 / -1; }
    .fl-device ul { margin-top: 24px; }
    /* the render straight under the paragraph, the list (and Fether Pro's
       points) under the render */
    .fl-device__art { order: 1; }
    .fl-device ul { order: 2; }
    .fl-device__points { order: 3; }
}


.fl-device__n {
    display: block;
    margin-bottom: 18px;
    font: 500 12px/1 var(--display);
    letter-spacing: .2em;
    color: var(--r);
}

.fl-device__n::before {
    content: "0";
}

.fl-device h3 {
    font: 700 clamp(22px, 3.6vw, 56px)/.92 var(--display); /* below the section's title at every width */
    text-transform: uppercase;
    letter-spacing: -.02em;
}

.fl-device h3 small {
    font-size: .5em;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--k2);
}

.fl-device__role {
    margin-top: 10px;
    font: 500 12px/1.2 var(--display);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--k2);
}

.fl-device ul li {
    display: flex;
    gap: 12px;
    align-items: baseline;
    padding: 10px 0 9px;
    border-bottom: 1px solid var(--rule);
    font: 500 clamp(13px, 1.1vw, 15px)/1.35 var(--display);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.fl-device ul li:first-child {
    padding-top: 0;
}

.fl-device ul li::before {
    content: "";
    flex: none;
    width: 6px;
    height: 6px;
    border: 1px solid var(--k);
    border-radius: 50%;
    background: var(--k);
    translate: 0 -2px;
}

.fl-device__art {
    margin-top: clamp(40px, 6vw, 88px);
}

.fl-device__art img {
    display: block;
    width: 100%;
    height: auto;
}

/* Fether Lite: the puck animation (video/fether-lite-puck.webm, with
   alpha), played through once and then looped from its gestures
   (next.js, data-loop-from); the camera pushes in until the hand fills the frame,
   so all four edges fade out into the page. */
/* Fether Pro's render, beside its text like Fether Lite's (below). Its hand
   is drawn smaller in its frame than Lite's (349 px tall in the last frame,
   against 487), so it is shown at 1.4 times the row's width and the two
   hands read the same size; its hand's right edge (65.6% across its frame
   once it loops) is set on the row's right edge, and the rest of the frame
   runs on into the margin (#fl cuts it off at the window). */
@media (min-width: 861px) {
    /* Beside the text, its left side fades out up to just past the text's
       right edge (--under, from the frame's left, set by next.js), so the
       band, spread wide at the start, does not run under the words. */
    .fl-device .fl-device__art--pro video {
        --under: 0px;
        --under-fade: 140px; /* the fade's length: no further than the hand (next.js) */
        -webkit-mask-image:
            linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
            linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent),
            linear-gradient(to right, transparent var(--under), #000 calc(var(--under) + var(--under-fade)));
        -webkit-mask-composite: source-in;
        mask-image:
            linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
            linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent),
            linear-gradient(to right, transparent var(--under), #000 calc(var(--under) + var(--under-fade)));
        mask-composite: intersect;
    }

    .fl-device .fl-device__art--pro video {
        width: 189%; /* 1.35 times its first 140% */
        /* as tall as it was; the hand's right edge (65.6% across) half-way
           out from the row's edge (100% - 65.6% of 189%) to the window's,
           across the margin beside the centred row */
        margin: -13.78% 0 -13.78% calc(-23.98% + (100vw - 100%) / 4);
        /* raised so the opening band (centred 53.3% down its frame) lines
           up with the "6 (DoF) IMU" bullet */
        translate: 0 -8.56%;
    }
}

/* Fether Pro: its render (video/fether-pro.webm, the 1.5x render, frames 0-400), played
   through once and then looped from frame 259 (8.65 s), where only the
   fingers still move, so frame 400 runs straight back into it. */
/* On narrow screens, under the text: each render at twice the row's width,
   centred on it, its extra height taken back by negative margins (a share
   of the row's width) so it is as tall as a 16:9 frame the row's width;
   their hands, the middle third of the frame once they loop, fill the row,
   and the rest runs past it (#fl cuts it off at the window). */
@media (max-width: 860px) {
    .fl-device .fl-device__art--film video {
        width: 280%; /* 1.4 times the old 200% */
        margin: -39.375% 0 -39.375% -90%;
    }

    /* Pro's 1.35 times that, centred, left as tall as its hand needs */
    .fl-device .fl-device__art--pro video {
        width: 270%;
        margin: -40.9% 0 -40.9% -85%;
    }
}

.fl-device__art--pro video,
.fl-device__art--film video {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    -webkit-mask-image:
        linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
        linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
    -webkit-mask-composite: source-in;
    mask-image:
        linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
        linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
    mask-composite: intersect;
}

/* Fether Lite in use: one film of the real gestures with the interface
   answering them (lite-demo), under the device's points, square at the
   corners. It arrives as if from the distance: transparent, blurred and at
   80% of its size, it grows, fades up and comes into focus, its film
   holding still until it is in place (next.js data-fade-loop). Once in
   focus no filter is left on it.
   - Wide screens: on a timer, once the Fether Lite render has played for
     2 seconds; it goes back the same way when its film ends, then comes
     up again and plays from the start.
   - Phones: with the scroll, in place by the time it is half-way up the
     screen (and back the same way, scrolling up); it loops while in place.
     The team's cards arrive the same way, with the scroll, at every width. */
.fl-device .fl-demo {
    grid-column: 1 / span 5;
    margin-top: clamp(24px, 3vw, 40px);
}

@media (min-width: 861px) {
    .fl-device .fl-demo {
        opacity: 0;
        scale: .8;
        filter: blur(12px);
        transition: opacity 1.2s ease, scale 1.6s cubic-bezier(.2, .7, .3, 1), filter 1.6s cubic-bezier(.4, 0, .3, 1);
    }

    .fl-device .fl-demo.is-shown {
        opacity: 1;
        scale: 1;
        filter: none; /* eases from the blur as from blur(0), then leaves no filter on the playing film */
    }
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        /* Arriving as if from the distance: transparent, blurred and at 80%
           of its size, it grows, fades up and comes into focus. */
        @keyframes demo-arrive {
            from {
                opacity: 0;
                scale: .8;
                filter: blur(12px);
                animation-timing-function: cubic-bezier(.25, .6, .3, 1); /* eases into place */
            }
            to {
                opacity: 1;
                scale: 1;
                filter: none;
            }
        }

        /* The team's cards arrive so, each with the scroll, at every width,
           in place once 40% of the way through the screen; this takes the
           place of their fade up (next.js, .fl-fade). */
        /* Staggered along each row: the card's place in its row (--col,
           0 from the left, next.js) holds it back 10% of its trip onto
           the screen per place, left to right. */
        .fl-team .fl-person {
            animation: demo-arrive linear both;
            animation-timeline: view();
            animation-range: entry calc(var(--col, 0) * 10%) cover calc(40% + var(--col, 0) * 6%);
        }

        html.fl-motion .fl-team .fl-person.fl-fade {
            transform: none;
            transition: none;
        }
    }

    /* Fether Lite in use arrives so with the scroll on phones only. */
    @media (max-width: 860px) and (prefers-reduced-motion: no-preference) {
        .fl-device .fl-demo {
            animation: demo-arrive linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 50%;
        }
    }
}

.fl-device .fl-demo video {
    display: block;
    width: 100%;
    height: auto;
    background: var(--k);
}

@media (max-width: 860px) {
    .fl-device .fl-demo { grid-column: 1 / -1; order: 3; }
}

@media (min-width: 861px) {
    .fl-device:has(.fl-device__art--film) > .fl-demo { grid-row: 4; }
}

/* Across the whole row, behind the name and its text and centred on them,
   so the hand reads at about the height of the text beside it; the text
   sits over the render's empty left side (on narrow screens it stays
   underneath, across the column). */
@media (min-width: 861px) {
    .fl-device__art--film {
        grid-column: 1 / -1;
        grid-row: 1 / span 4; /* centred on the text and the demo under it,
                                 top divider to the demo's bottom */
        align-self: center;
        margin-top: 0;
        pointer-events: none;
        /* its hand's right edge (72.9% across its frame once it loops) on
           the row's right edge; the rest of the frame runs on into the
           margin (#fl cuts it off at the window) */
        translate: 27.1% 0;
    }
    /* 1.4 times the row's width, grown leftward from that hand edge:
       its hand's right edge, 72.9% of 140% across, kept where 72.9% of
       100% was (-29.16%), then nudged 5% of the row right for balance */
    .fl-device .fl-device__art--film video {
        width: 140%;
        margin-left: -24.16%;
        /* its empty top and bottom trimmed so it never sets the row's
           height: the section ends with the text, the render's frame runs
           over and under it (transparent there), its hand centred on it */
        margin-top: -20%;
        margin-bottom: -20%;
    }
    /* When the render is taller than the text, the spare fourth row takes
       the difference, so the text stays packed under the name instead of
       spreading out down the render. */
    .fl-device:has(.fl-device__art--film) {
        grid-template-rows: auto auto auto;
    }
    .fl-device:has(.fl-device__art--film) > :not(.fl-device__art) {
        position: relative;
        z-index: 1;
    }
    .fl-device:has(.fl-device__art--film) > .fl-device__meta { grid-row: 1; }
    .fl-device:has(.fl-device__art--film) > .fl-device__lede { grid-row: 2; }
    .fl-device:has(.fl-device__art--film) > ul { grid-row: 3; }

    /* Fether Pro the same way, with its points as a fourth row of text. */
    .fl-device__art--pro {
        grid-column: 1 / -1;
        grid-row: 1 / span 5;
        align-self: center;
        margin-top: 0;
        pointer-events: none;
    }
    .fl-device:has(.fl-device__art--pro) {
        grid-template-rows: auto auto auto auto 1fr;
    }
    .fl-device:has(.fl-device__art--pro) > :not(.fl-device__art) {
        position: relative;
        z-index: 1;
    }
    .fl-device:has(.fl-device__art--pro) > .fl-device__meta { grid-row: 1; }
    .fl-device:has(.fl-device__art--pro) > .fl-device__lede { grid-row: 2; }
    .fl-device:has(.fl-device__art--pro) > ul { grid-row: 3; }
    .fl-device:has(.fl-device__art--pro) > .fl-device__points { grid-row: 4; }
}

.fl-shared {
    margin-top: clamp(40px, 5vw, 72px);
    font: 500 11px/1.4 var(--display);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--k2);
}

.fl-shared::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 10px;
    border-radius: 50%;
    background: var(--k);
    translate: 0 -2px;
}

/* ---- 06 From research to pilot ---- */
.fl-stages {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    margin-top: clamp(96px, 12vw, 180px);
    border-top: 1px solid var(--rule);
}

.fl-stages li {
    position: relative;
    display: grid;
    gap: 22px;
    padding: 20px 16px 0 0;
}

.fl-stages li::before {
    content: "";
    position: absolute;
    top: -5px;
    left: 0;
    width: 9px;
    height: 9px;
    border: 1px solid var(--k);
    border-radius: 50%;
    background: var(--backdrop-color, #769298);
}

.fl-stages li.is-done {
    margin-top: -1.5px;
    border-top: 2px solid var(--k);
}

.fl-stages li.is-done::before {
    background: var(--k);
}

.fl-stages .fl-num {
    font: 700 clamp(36px, 4.4vw, 68px)/.8 var(--display);
    letter-spacing: -.03em;
}

.fl-stages li:not(.is-done) .fl-num {
    color: transparent;
    -webkit-text-stroke: 1px var(--k);
}

.fl-stages b {
    font: 500 13px/1 var(--display);
    text-transform: uppercase;
    letter-spacing: .2em;
}

.fl-here {
    position: absolute;
    top: -30px;
    left: 0;
    font: 500 11px/1 var(--display);
    letter-spacing: .18em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--r);
}

/* On a phone the four stages stay on one line: smaller numbers and names,
   tighter spacing. */
@media (max-width: 760px) {
    .fl-stages li { gap: 14px; padding-right: 6px; }
    .fl-stages .fl-num { font-size: clamp(26px, 8.4vw, 40px); }
    .fl-stages b { font-size: 10px; letter-spacing: .12em; }
    .fl-here { font-size: 9px; letter-spacing: .14em; }
}

.fl-cta {
    display: inline-flex;
    align-items: center;
    gap: .6em;
    margin-top: clamp(28px, 4vw, 44px);
    padding-bottom: 6px;
    border-bottom: 2px solid var(--k);
    text-decoration: none;
    font: 700 clamp(16px, 1.4vw, 20px)/1 var(--display);
    text-transform: uppercase;
    letter-spacing: .08em;
    transition: gap .2s, border-color .2s;
}

.fl-cta:hover {
    gap: 1em;
    border-color: var(--r);
}

.fl-cta:focus-visible,
.fl-form button:focus-visible {
    outline: 2px solid var(--r);
    outline-offset: 4px;
}

/* ---- 07 Contact ---- */
/* The form waits closed under the Stage section's last line, behind a call
   to action; the link opens it smoothly in place (its height grows from
   nothing, the form fading in) and closes it again. Closed, it is out of
   reach of the keyboard and screen readers too (visibility). */
.fl-ask__open {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    margin-top: clamp(28px, 3.5vw, 48px);
    padding: 0 0 6px;
    border: 0;
    border-bottom: 1px solid var(--k);
    background: none;
    font: 500 clamp(14px, 1.2vw, 16px)/1 var(--display);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--k);
    cursor: pointer;
}

.fl-ask__open span {
    color: var(--r);
    transition: rotate .4s, translate .2s;
}

.fl-ask__open:hover span {
    translate: 4px 0;
}

.fl-ask__open[aria-expanded="true"] span {
    rotate: 90deg;
    translate: 0;
}

.fl-ask__panel {
    display: grid;
    grid-template-rows: 0fr;
    visibility: hidden;
    transition: grid-template-rows .7s cubic-bezier(.2, .7, .3, 1), visibility 0s .7s;
}

.fl-ask__panel.is-open {
    grid-template-rows: 1fr;
    visibility: visible;
    transition: grid-template-rows .7s cubic-bezier(.2, .7, .3, 1), visibility 0s;
}

.fl-ask__inner {
    min-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: opacity .4s;
}

.fl-ask__panel.is-open .fl-ask__inner {
    opacity: 1;
    transition: opacity .6s .15s;
}

.fl-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px clamp(24px, 4vw, 64px);
    max-width: 1040px;
    margin-top: clamp(40px, 6vw, 88px);
}

.fl-form label {
    display: block;
    padding-top: 18px;
}

.fl-form label.is-wide {
    grid-column: 1 / -1;
}

.fl-form label > span {
    display: flex;
    gap: 10px;
    font: 500 11px/1 var(--display);
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--k2);
}

.fl-form label > span i {
    font-style: normal;
    color: var(--r);
}

.fl-form input,
.fl-form textarea {
    display: block;
    width: 100%;
    margin-top: 6px;
    padding: 10px 0;
    border: 0;
    border-bottom: 1px solid var(--k);
    border-radius: 0;
    background: transparent;
    color: var(--k);
    font: 400 18px/1.4 var(--body);
    outline: 0;
}

.fl-form textarea {
    min-height: 120px;
    resize: vertical;
}

.fl-form input:focus,
.fl-form textarea:focus {
    padding-bottom: 9px;
    border-bottom: 2px solid var(--k);
}

.fl-form input::placeholder,
.fl-form textarea::placeholder {
    color: var(--k2);
    opacity: .7;
}

.fl-form__foot {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px 28px;
    margin-top: 28px;
}

.fl-form button {
    padding: 16px 28px 15px;
    border: 0;
    border-radius: 0;
    background: var(--k);
    color: var(--p);
    font: 700 15px/1 var(--display);
    text-transform: uppercase;
    letter-spacing: .14em;
    cursor: pointer;
    transition: background .2s;
}

.fl-form button:hover {
    opacity: .86;
}

.fl-form button[disabled] {
    background: #4A5459;
    cursor: progress;
}

/* A field only bots fill in (Web3Forms drops what arrives with it ticked). */
.fl-form__trap {
    position: absolute;
    left: -9999px;
    opacity: 0;
    pointer-events: none;
}

.fl-form__status {
    font: 500 12px/1.3 var(--display);
    letter-spacing: .16em;
    text-transform: uppercase;
}

@media (max-width: 640px) {
    .fl-form { grid-template-columns: 1fr; }
}

/* ---- 08 Team: cards, as before but lighter ---- */
.fl-team {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
    gap: clamp(16px, 2vw, 24px);
    margin-top: clamp(40px, 6vw, 88px);
}

/* The four leads on one row wherever four fit. */
@media (min-width: 1100px) {
    .fl-team { grid-template-columns: repeat(4, 1fr); }
}

.fl-person {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--k);
}

.fl-person__img {
    position: relative;
    aspect-ratio: 1;
    overflow: hidden;
    border-bottom: 1px solid var(--k);
    background: var(--k);
}

.fl-person__img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}


.fl-person__body {
    display: grid;
    gap: 10px;
    align-content: start;
    padding: 16px 16px 20px;
}

/* Each name on two lines, first and last, at every width, so the cards
   match. */
.fl-person h3 {
    width: min-content;
    font: 700 clamp(20px, 1.7vw, 26px)/.98 var(--display);
    text-transform: uppercase;
}

.fl-role {
    justify-self: start;
    font: 500 11px/1 var(--display);
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--r);
}

.fl-person p {
    font-size: 14px;
    line-height: 1.55;
    color: rgba(20, 25, 28, .78);
}

/* On phones, two smaller cards to a row. */
@media (max-width: 640px) {
    .fl-team {
        grid-template-columns: repeat(2, 1fr);
        gap: 12px;
    }


    .fl-person__body {
        gap: 6px;
        padding: 10px 10px 14px;
    }

    .fl-person h3 {
        font-size: 16px;
    }

    .fl-role {
        font-size: 9px;
        line-height: 1.3;
        letter-spacing: .14em;
    }

    .fl-person p {
        font-size: 12px;
        line-height: 1.45;
    }
}

/* ---- Footer: a dark band ---- */
.fl-foot {
    padding-bottom: clamp(40px, 5vw, 72px);
}

/* The logo (brand/Logo "left aligned with LABS"), half the column's width. */
.fl-foot__word {
    padding-top: clamp(24px, 3vw, 40px);
    border-top: 2px solid var(--k);
}

.fl-foot__logo {
    display: block;
    width: 50%;
    height: auto;
}

.fl-foot__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
    margin-top: clamp(36px, 5vw, 64px);
    font-size: 15px;
    line-height: 1.55;
}

.fl-foot__grid .fl-label {
    display: block;
    margin-bottom: 8px;
}


@media (max-width: 760px) {
    .fl-foot__grid { grid-template-columns: 1fr 1fr; }
}

/* ---- Motion: each piece fades up as it comes onto the screen (next.js
   marks them .fl-fade and staggers them with --fade-delay). It moves by
   transform, not translate, which some pieces use for their placing. */
html.fl-motion .fl-fade {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity .9s cubic-bezier(.2, .7, .3, 1), transform .9s cubic-bezier(.2, .7, .3, 1);
    transition-delay: var(--fade-delay, 0s);
}

html.fl-motion .fl-fade.is-in {
    opacity: 1;
    transform: none;
}

/* Pieces with their own hover motion keep it alongside the fade. */
html.fl-motion .fl-form button.fl-fade {
    transition: opacity .9s cubic-bezier(.2, .7, .3, 1), transform .9s cubic-bezier(.2, .7, .3, 1),
        background .2s;
    transition-delay: var(--fade-delay, 0s), var(--fade-delay, 0s), 0s;
}

/* The stages build out in turn once the timeline comes up the screen:
   the hairline draws across, then each stage's node pops in and its
   number and name rise, the heavy line running on from each finished
   stage to the next as that one's node lands; last, "We are here"
   appears over stage 03, and its node keeps a slow pulse. Each stage
   starts --t after the timeline arrives. It plays again each time the
   timeline comes back into view (next.js). */
html.fl-motion .fl-stages.fl-rise {
    opacity: 1;
    translate: none;
}

html.fl-motion .fl-stages {
    position: relative;
    border-top-color: transparent;
}

html.fl-motion .fl-stages::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--rule);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 1.6s cubic-bezier(.65, 0, .35, 1) .1s;
}

html.fl-motion .fl-stages li:nth-child(1) { --t: .35s; }
html.fl-motion .fl-stages li:nth-child(2) { --t: .9s; }
html.fl-motion .fl-stages li:nth-child(3) { --t: 1.45s; }
html.fl-motion .fl-stages li:nth-child(4) { --t: 2s; }

html.fl-motion .fl-stages li::before {
    z-index: 1;
    transform: scale(0);
    transition: transform .5s cubic-bezier(.34, 1.56, .64, 1) var(--t);
}

html.fl-motion .fl-stages li.is-done {
    border-top-color: transparent;
}

html.fl-motion .fl-stages li.is-done::after {
    content: "";
    position: absolute;
    top: -2px;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--k);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .55s cubic-bezier(.45, 0, .55, 1) calc(var(--t) + .05s);
}

html.fl-motion .fl-stages .fl-num,
html.fl-motion .fl-stages b {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .7s cubic-bezier(.2, .7, .3, 1) calc(var(--t) + .1s),
        transform .7s cubic-bezier(.2, .7, .3, 1) calc(var(--t) + .1s);
}

html.fl-motion .fl-stages b {
    transition-delay: calc(var(--t) + .22s);
}

html.fl-motion .fl-stages .fl-here {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .6s ease 2.7s, transform .6s cubic-bezier(.2, .7, .3, 1) 2.7s;
}

html.fl-motion .fl-stages.is-in::before,
html.fl-motion .fl-stages.is-in li.is-done::after {
    transform: none;
}

html.fl-motion .fl-stages.is-in li::before {
    transform: none;
}

html.fl-motion .fl-stages.is-in .fl-num,
html.fl-motion .fl-stages.is-in b,
html.fl-motion .fl-stages.is-in .fl-here {
    opacity: 1;
    transform: none;
}

/* While the timeline is put back to its start, off the screen, nothing
   animates (next.js). */
html.fl-motion .fl-stages.is-reset,
html.fl-motion .fl-stages.is-reset::before,
html.fl-motion .fl-stages.is-reset *,
html.fl-motion .fl-stages.is-reset *::before,
html.fl-motion .fl-stages.is-reset *::after {
    transition: none !important;
}

/* The current stage's pulse: a ring that swells off its node and fades. */
html.fl-motion .fl-stages.is-in li.is-now::after {
    content: "";
    position: absolute;
    top: -5px;
    left: 0;
    width: 9px;
    height: 9px;
    box-sizing: border-box;
    border: 1px solid var(--r);
    border-radius: 50%;
    opacity: 0;
    animation: fl-now 2.4s cubic-bezier(.2, .7, .3, 1) 3s infinite;
}

@keyframes fl-now {
    0% { opacity: .9; transform: scale(1); }
    100% { opacity: 0; transform: scale(3.2); }
}


/* ---- The riding line (next.js) ----
   The dividers show only once the riding line has left them (is-lined);
   the line itself (.fl-lead) is drawn over the page, fixed to the screen. */
html.fl-lines .fl-head:not(.is-lined) { border-bottom-color: transparent; }
html.fl-lines .fl-device:not(.is-lined) { border-top-color: transparent; }

.fl-lead {
    position: fixed;
    z-index: 40;
    pointer-events: none;
}

.fl-lead[hidden] {
    display: none;
}


/* The method, under the trigger's sentence in the same column: a divider
   with its label, its name as a subheading (60 % of a section title), its
   paragraph. The bold sentence sits under the clip in the other column. */
.fl-trig-copy .fl-head--next {
    margin: clamp(48px, 5vw, 80px) 0 clamp(20px, 2vw, 28px);
}

.fl-trig-copy { container-type: inline-size; }

/* …and never wider than its column (the word is 11.41 em across). */
#trigger .fl-word {
    font-size: max(24px, min(var(--title-size) * .6, 100cqi / 11.6));
}

#trigger .fl-mech-copy { margin-top: 0; }

.fl-trig-media figure { margin: 0; }


/* Balance (desktop): the two columns share one height. Left, the title and
   its sentence at the top, the method settled to the bottom; right, the
   clip grows to fill (cropped, never squashed), its foot level with the
   method's last line. */
@media (min-width: 861px) {
    .fl-trig-open { align-items: stretch; }

    .fl-trig-copy,
    .fl-trig-media { display: flex; flex-direction: column; }

    #trigger .fl-lede { font-size: clamp(16px, 1.3vw, 19px); }

    .fl-trig-copy > .fl-lede:not(.fl-mech-copy) { margin-bottom: clamp(48px, 5vw, 80px); }
    .fl-trig-copy .fl-head--next { margin-top: auto; }

    .fl-trig-media figure {
        position: relative;
        flex: 1 1 auto;
        min-height: 320px;
    }

    .fl-trig-media figure video {
        position: absolute;
        inset: 0;
        height: 100%;
        aspect-ratio: auto;
    }
}

/* The sensors sentence sits in the clip's frame, bottom left: the clip
   ends just above it and fades into the frame's own dark, so the words
   never cross the hand. */
#trigger .fl-trig-media figure {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #0E0E0E;
}

#trigger .fl-trig-media .fl-method {
    position: relative;
    margin: -64px 0 0;
    padding: 64px clamp(16px, 2vw, 28px) clamp(14px, 1.8vw, 24px);
    background: linear-gradient(to bottom, rgba(14, 14, 14, 0), #0E0E0E 64px);
    pointer-events: none;
}

@media (min-width: 861px) {
    #trigger .fl-trig-media figure video {
        position: relative;
        inset: auto;
        flex: 1 1 0;
        min-height: 0;
    }
}

#trigger .fl-trig-media .fl-method .fl-lede {
    margin: 0;
    max-width: none;
    font-size: clamp(14px, 1.1vw, 16px);
    font-weight: 400;
    line-height: 1.5;
    color: rgba(238, 243, 244, .68);
}

@media (max-width: 860px) {
    #trigger .fl-trig-media .fl-method { margin-top: -40px; padding: 40px 14px 12px; background: linear-gradient(to bottom, rgba(14, 14, 14, 0), #0E0E0E 40px); }
    #trigger .fl-trig-media .fl-method .fl-lede { font-size: 12.5px; line-height: 1.45; }
}

/* Phones: the clip follows the trigger's sentence, ahead of the method. */
@media (max-width: 860px) {
    .fl-trig-open { display: flex; flex-direction: column; gap: 0; }
    .fl-trig-copy, .fl-trig-media { display: contents; }
    .fl-trig-copy > .fl-mega { order: 1; }
    .fl-trig-copy > .fl-lede:not(.fl-mech-copy) { order: 2; }
    .fl-trig-media figure { order: 3; margin-top: 32px; }
    .fl-trig-copy .fl-head--next { order: 4; align-self: stretch; }
    #trigger .fl-word { order: 5; }
    #trigger .fl-mech-copy { order: 6; }
}
