@font-face {
    font-family: "Epilogue";
    src: url("assets/fonts/epilogue-var-latin.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    /* Not swap: the wordmark is sized from Epilogue's own advances. */
    font-display: block;
}

:root {
    --kimberley-font: "Epilogue", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --kimberley-e-out: cubic-bezier(0.16, 1, 0.3, 1);
    --kimberley-e-quart: cubic-bezier(0.25, 1, 0.5, 1);
    --kimberley-e-inout: cubic-bezier(0.83, 0, 0.17, 1);
    --kimberley-e-ui: cubic-bezier(0.4, 0, 0.2, 1);
    --kimberley-paper: #f6f6ef;
    --kimberley-ink: #0b0384;
    /* Off her skirt in the poster. 3.77:1 on paper, so large text only. */
    --kimberley-skirt: #628293;
    /* The top of the sky gradient the room's window looks out on, so the ending and the
       room behind it are the same daylight. Ink on it is 8.09:1. */
    --kimberley-sky: #9fc0d8;
    /* Halfway from that sky to the wordmark's skirt. 2.51:1 on the cream: the sky itself is
       1.76:1 there and the line would draw almost invisibly. */
    --kimberley-haze: #81a1b6;
    /* The skirt taken down until it clears 4.5:1 on the cream, which the skirt itself does
       not at 3.77:1. The second voice: supporting copy, never a title. */
    --kimberley-aside: #4d6a7a;
}

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

html {
    overflow-x: clip;
}

body {
    margin: 0;
    min-height: 100svh;
    overflow-x: clip;
    background: var(--kimberley-paper);
    color: var(--kimberley-ink);
    font-family: var(--kimberley-font);
    font-synthesis: none;
}

/* Continues the ground the last panel ends on rather than cutting back to paper. */
.kimberley-room {
    background: var(--kimberley-sky);
}

.kimberley-room-track {
    height: 500svh;
}

.kimberley-room-stage {
    position: sticky;
    top: 0;
    display: grid;
    height: 100svh;
    overflow: clip;
    place-items: center;
}

.kimberley-room-gl,
.kimberley-room-said {
    grid-area: 1 / 1;
}

.kimberley-room-gl {
    place-self: stretch;
    width: 100%;
    height: 100%;
    opacity: 0;
    transition: opacity 700ms var(--kimberley-e-out);
}

.kimberley-room-live .kimberley-room-gl {
    opacity: 1;
}

/* The room in words, under the canvas. Hidden once it draws but never display none, or a
   screen reader loses it. The margin is here, not on the stage, which would inset the
   canvas with it. */
.kimberley-room-said {
    width: min(34rem, calc(100% - 2 * clamp(24px, 6vw, 108px)));
    color: var(--kimberley-ink);
    font-size: clamp(1rem, 1.15vw, 1.0625rem);
    line-height: 1.62;
    text-wrap: pretty;
}

.kimberley-room-live .kimberley-room-said {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.kimberley-room-title {
    margin: 0 0 0.6em;
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: 320;
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.kimberley-stage {
    position: sticky;
    top: 0;
    height: 100svh;
    /* clip, not hidden: a real edge without a scroll container. */
    overflow: clip;
    font-size: calc(100vw / 3.043);
}

/* Measured off the woff2 at wght 310, kerning off: OLIVIER is 3.2230em of ink and six
   -0.03em gaps give the 3.043em the stage divides the viewport by. The offsets cancel the
   O's side bearing and the line box under the baseline. */
.kimberley-wordmark {
    position: absolute;
    left: -0.0525em;
    bottom: -0.213em;
    margin: 0;
    color: var(--kimberley-skirt);
    font-size: inherit;
    font-weight: 310;
    letter-spacing: -0.03em;
    font-kerning: none;
    line-height: 1;
    white-space: nowrap;
}

/* Epilogue's tittle at 2.4x, clearing the cap by the 0.1326em it clears the x-height. */
.kimberley-dot {
    position: absolute;
    bottom: 0.87965em;
    width: 0.23112em;
    height: 0.20256em;
    border-radius: 0.11556em / 0.10128em;
    background-color: var(--kimberley-skirt);
}

/* Advances to each I, plus the 0.1142em stem centre, less the wordmark offset and half
   the dot. */
.kimberley-dot-one { left: 1.05369em; }
.kimberley-dot-two { left: 1.81319em; }

/* Open by default: with no scroll timeline the page is the photograph. */
.kimberley-window {
    position: absolute;
    inset: 0;
    margin: 0;
    clip-path: inset(0 0 0 0 round 0);
}

/* The still is the truth: autoplay fails for reasons the page cannot detect, and iOS Low
   Power Mode does not set prefers-reduced-motion. */
.kimberley-window-still,
.kimberley-window-film {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.kimberley-window-film {
    opacity: 0;
    transition: opacity 400ms var(--kimberley-e-ui);
}

.kimberley-is-running .kimberley-window-film {
    opacity: 1;
}


/* First half of a sentence the wordmark finishes, in the wordmark's colour so the two read
   as one line. Skirt on paper is 3.77:1, which is under the 4.5:1 AA wants at this size. */
.kimberley-hello {
    position: absolute;
    left: 0;
    right: 0;
    top: 4svh;
    margin: 0;
    color: var(--kimberley-skirt);
    font-size: clamp(0.875rem, 1.05vw, 1.125rem);
    font-weight: 380;
    letter-spacing: 0.04em;
    line-height: 1.1;
    text-align: center;
}

/* On the wordmark's baseline and size, in the slot it sank out of. 387.85vw is the
   sentence at wght 400, -0.03em, kerning off: re-measure on every copy or weight change. */
.kimberley-line {
    position: absolute;
    left: 0;
    bottom: -0.213em;
    z-index: 1;
    margin: 0;
    color: var(--kimberley-paper);
    font-size: inherit;
    font-weight: 400;
    letter-spacing: -0.03em;
    font-kerning: none;
    line-height: 1;
    white-space: nowrap;
    transform: translateX(100vw);
}

.kimberley-sheet {
    position: absolute;
    inset: 0;
    z-index: 2;
    background: var(--kimberley-paper);
    transform: translateY(100%);
}

/* Its own layer: the sheet is already spending its one animation on rising. */
.kimberley-ground {
    position: absolute;
    inset: 0;
    background: var(--kimberley-paper);
}

/* Opens light on the cream and darkens into the type's own ink, so the line arrives as a
   drawn mark and ends as the hand that wrote the ampersand. The panels paint over it, so it
   passes behind the words. pathLength 1 makes the dash a plain 0 to 1 whatever the arc
   length is. */
.kimberley-thread {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    color: var(--kimberley-haze);
    pointer-events: none;
}

.kimberley-thread path {
    fill: none;
    stroke: currentColor;
    stroke-width: 22;
    stroke-linecap: round;
    stroke-dasharray: 1;
}

/* The paragraph holds its row from the start, so nothing shifts under the title when it
   arrives. */
.kimberley-panel {
    position: absolute;
    inset: 0;
    display: grid;
    align-content: center;
    justify-items: start;
    gap: clamp(2rem, 5vh, 4.5rem);
    padding-inline: clamp(24px, 6vw, 108px);
}

/* Parked right with no timeline to move it, so the fallback shows one panel, not two
   stacked. */
.kimberley-panel-two {
    transform: translateX(120vw);
    color: var(--kimberley-ink);
}

/* Broken by hand at 7.61, 7.18 and 6.87em so each line rises on its own. The clamp floor
   keeps the longest inside 320px, and is not a display size. */
.kimberley-close {
    margin: 0;
    font-size: clamp(2rem, 8vw, 8.5rem);
    font-weight: 280;
    letter-spacing: -0.03em;
    line-height: 1.02;
}

.kimberley-close-line,
.kimberley-close-in {
    display: block;
}

/* The drawn ampersand hangs off this, so it rides the arrival as well as the departure. */
.kimberley-close-in {
    position: relative;
}

.kimberley-close-line {
    position: relative;
    white-space: nowrap;
}

/* Held upright: the fallback families have an italic and Epilogue does not. */
.kimberley-close-ruled em {
    font-style: normal;
}

/* The one italic letterform on the page, drawn because Epilogue has no italic: Epilogue
   Italic's ampersand at wght 280, one closed contour, so a single dash runs it without
   lifting. 6.4975em is the advance of "visuelt design " less the viewBox's padding, 0.023em
   the 0.7875em baseline less the glyph height. Invisible at rest, so a page with no
   timeline keeps the roman ampersand that is really in the text. */
.kimberley-amp-pen {
    position: absolute;
    top: 0.023em;
    left: 6.4975em;
    width: 0.6755em;
    height: 0.793em;
}

/* 320 units against a 93-unit stroke, clipped to the glyph, so the travelling nib lays the
   letter down solid. Tracing the outline at a hairline instead put paper between two lines
   for a moment, and that gap read as a white flash. At dashoffset 0 this is the filled
   glyph exactly. */
.kimberley-amp-nib {
    fill: none;
    stroke: currentColor;
    stroke-width: 320;
    stroke-linecap: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
}

/* On the line, not around the word: an inline box's content area is not defined precisely
   enough to hang a measured rule off. 1.9035em and 4.172em are the advances of "Jeg " and
   "brænder"; 0.0565em is the stem. */
.kimberley-close-ruled::after {
    content: "";
    position: absolute;
    top: 0.8575em;
    left: 1.9035em;
    width: 4.172em;
    height: 0.0565em;
    background: currentColor;
    transform-origin: left;
}

/* Ink on the sky ground is 8.09:1, so the 24px floor here is a display decision and not a
   contrast one. */
.kimberley-lead {
    position: relative;
    top: -14vh;
    width: min(40rem, 100%);
    margin: 0;
    font-size: clamp(1.5rem, 2.2vw, 1.875rem);
    font-weight: 400;
    letter-spacing: -0.015em;
    line-height: 1.45;
    /* balance, not pretty: pretty left a 579px first line against a 191px last one. */
    text-wrap: balance;
}

/* inline-block so a word can be transformed at all. */
.kimberley-lead-word {
    display: inline-block;
}

/* Offset, not a bigger gap: the grid is centred, so a gap lifts the title as much as it
   drops the paragraph. It steps back a colour as well as a size, so the title carries the
   statement and this reads as the aside it is. 5.29:1 at 16px. */
.kimberley-note {
    position: relative;
    top: 1.25rem;
    justify-self: end;
    color: var(--kimberley-aside);
    /* 52 characters, under the usual 62 to 72: a column beside the title, not body copy. */
    width: min(27rem, 100%);
    margin: 0;
    font-size: clamp(1rem, 1.15vw, 1.0625rem);
    font-weight: 400;
    line-height: 1.62;
    text-wrap: pretty;
}

/* Starts off to the right, so travelling left the sentence passes in reading order. */
@keyframes kimberley-line-by {
    from { transform: translateX(100vw); }
    to { transform: translateX(-387.85vw); }
}

@keyframes kimberley-hello-in {
    from { opacity: 0; transform: translateY(0.6em); }
    to { opacity: 1; transform: translateY(0); }
}

/* Gone before the dots gather at 40%, and upward, out of the frame the name will fill. */
@keyframes kimberley-hello-out {
    0%, 10% { opacity: 1; transform: translateY(0); }
    38%, 100% { opacity: 0; transform: translateY(-0.5em); }
}

/* Up out of the floor, across the sentence's heading rather than along it. */
@keyframes kimberley-sheet-over {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}

/* 1.16925em and 1.92875em stand each half on 50vw, so the two open as one dot. */
@keyframes kimberley-seed-one {
    0% {
        transform: translate(calc(50vw - 1.16925em), calc(0.98093em - 50svh)) scale(0);
        border-radius: 0.11556em / 0.10128em;
        animation-timing-function: var(--kimberley-e-out);
    }
    22%, 27% {
        transform: translate(calc(50vw - 1.16925em), calc(0.98093em - 50svh)) scale(1);
        border-radius: 0.11556em / 0.10128em;
        animation-timing-function: var(--kimberley-e-out);
    }
    46%, 54% {
        transform: translate(calc(50vw - 1.28281em), calc(0.98093em - 50svh)) scale(1);
        border-radius: 0.10128em 0 0 0.10128em;
        animation-timing-function: var(--kimberley-e-out);
    }
    100% {
        transform: translate(0, 0) scale(1);
        border-radius: 0.11556em / 0.10128em;
    }
}

@keyframes kimberley-seed-two {
    0% {
        transform: translate(calc(50vw - 1.92875em), calc(0.98093em - 50svh)) scale(0);
        border-radius: 0.11556em / 0.10128em;
        animation-timing-function: var(--kimberley-e-out);
    }
    22%, 27% {
        transform: translate(calc(50vw - 1.92875em), calc(0.98093em - 50svh)) scale(1);
        border-radius: 0.11556em / 0.10128em;
        animation-timing-function: var(--kimberley-e-out);
    }
    46%, 54% {
        transform: translate(calc(50vw - 1.81519em), calc(0.98093em - 50svh)) scale(1);
        border-radius: 0 0.10128em 0.10128em 0;
        animation-timing-function: var(--kimberley-e-out);
    }
    100% {
        transform: translate(0, 0) scale(1);
        border-radius: 0.11556em / 0.10128em;
    }
}

/* 0.747em puts the cap line on the floor. The scroll runs it backwards. */
@keyframes kimberley-rise {
    from { transform: translateY(0.747em); }
    to { transform: translateY(0); }
}

/* The rise is the later name and wins the transform for 1.75s, so a fast scroll can hold
   the word up over the opening aperture. Opacity stays with the scroll and goes first. */
@keyframes kimberley-sink {
    0%, 12% { transform: translateY(0); opacity: 1; }
    40%, 60% { transform: translateY(0.747em); opacity: 1; }
    70%, 100% { transform: translateY(0.747em); opacity: 0; }
}

/* One turn about the pill's centre, 0.11356em to the side of each dot's: the flanking
   translates carry the rotation there so transform-origin stays where the load-in's scale
   needs it. Every keyframe holds the whole list or 180deg degenerates to a matrix. */
@keyframes kimberley-gather-one {
    0%, 40% {
        transform: translate(0, 0)
                   translate(0.11356em, 0) rotate(0deg) translate(-0.11356em, 0);
        border-radius: 0.11556em / 0.10128em;
    }
    60% {
        transform: translate(calc(50vw - 1.28281em), calc(0.98093em - 50svh))
                   translate(0.11356em, 0) rotate(0deg) translate(-0.11356em, 0);
        border-radius: 0.10128em 0 0 0.10128em;
    }
    78%, 100% {
        transform: translate(calc(50vw - 1.28281em), calc(0.98093em - 50svh))
                   translate(0.11356em, 0) rotate(180deg) translate(-0.11356em, 0);
        border-radius: 0.10128em 0 0 0.10128em;
    }
}

@keyframes kimberley-gather-two {
    0%, 40% {
        transform: translate(0, 0)
                   translate(-0.11356em, 0) rotate(0deg) translate(0.11356em, 0);
        border-radius: 0.11556em / 0.10128em;
    }
    60% {
        transform: translate(calc(50vw - 1.81519em), calc(0.98093em - 50svh))
                   translate(-0.11356em, 0) rotate(0deg) translate(0.11356em, 0);
        border-radius: 0 0.10128em 0.10128em 0;
    }
    78%, 100% {
        transform: translate(calc(50vw - 1.81519em), calc(0.98093em - 50svh))
                   translate(-0.11356em, 0) rotate(180deg) translate(0.11356em, 0);
        border-radius: 0 0.10128em 0.10128em 0;
    }
}

/* The pill the dots just made, to the em. */
@keyframes kimberley-aperture {
    0%, 78% { clip-path: inset(50% 50% round 0); }
    84% { clip-path: inset(calc(50% - 0.10128em) calc(50% - 0.23112em) round 0.10128em); }
    98%, 100% { clip-path: inset(0 0 0 0 round 0); }
}

/* 0.3em: far enough to read as a lift, short enough that the three never overlap. */
@keyframes kimberley-close-up {
    from { opacity: 0; transform: translateY(0.3em); }
    to { opacity: 1; transform: translateY(0); }
}

/* 95vw clears the longest line's right edge at 320px, where it is proportionally widest. */
@keyframes kimberley-sweep-out {
    from { transform: translateX(0); }
    to { transform: translateX(-95vw); }
}

@keyframes kimberley-thread-draw {
    from { stroke-dashoffset: 1; }
    to { stroke-dashoffset: 0; }
}

/* Cream to daylight. Both sit high on the lightness scale, 0.92 to 0.50, so the ramp out of
   the first panel never passes through a muddy neutral the way paper to a mid blue did. */
/* Ink by 78%, just before the closing sentence arrives at 77.5%, so the line has settled
   before there is anything to read over it. */
@keyframes kimberley-thread-turn {
    from { color: var(--kimberley-haze); }
    to { color: var(--kimberley-ink); }
}

@keyframes kimberley-ground-turn {
    from { background-color: var(--kimberley-paper); }
    to { background-color: var(--kimberley-sky); }
}

/* 0.5em, not a viewport: at this size a full traverse only ever reads as a slide. */
@keyframes kimberley-lead-in {
    from { opacity: 0; transform: translateY(0.5em); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes kimberley-rule-in {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
}

/* One gesture, from the top of the loop down the spine and round the bowl. It lands at 92%
   so the letter stands finished for a beat before the panel moves on. */
@keyframes kimberley-amp-write {
    from { stroke-dashoffset: 1; }
    92%, 100% { stroke-dashoffset: 0; }
}

@keyframes kimberley-amp-off {
    from { opacity: 1; }
    to { opacity: 0; }
}

/* Alone in its panel, so its whole life is one animation. It leaves before the title, on
   a 10vw drift rather than a traverse. */
@keyframes kimberley-note-up {
    0% { opacity: 0; transform: translate(0, 1.6rem); }
    33%, 55% { opacity: 1; transform: translate(0, 0); }
    100% { opacity: 0; transform: translate(-10vw, 0); }
}

@keyframes kimberley-fade {
    from { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .kimberley-stage {
        animation: kimberley-fade 500ms var(--kimberley-e-ui) both;
    }
}

@media (prefers-reduced-motion: no-preference) {
    .kimberley-wordmark {
        animation: kimberley-rise 750ms 1000ms var(--kimberley-e-quart) backwards;
    }
}

@supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
        /* A view timeline on the track, so the ranges below are progress through the
           sticky stage rather than through the document: contain is the 840svh it spends
           stuck. It was 700svh, grown so the ampersand and the sentence each have room;
           everything else kept its length in svh, hence the odd percentages. */
        .kimberley-track {
            height: 940svh;
            view-timeline-name: --kimberley-run;
            view-timeline-axis: block;
        }

        /* The load-in is the later name and wins the transform while it runs, the same
           trade the wordmark makes below. */
        .kimberley-hello {
            animation-name: kimberley-hello-out, kimberley-hello-in;
            animation-timeline: --kimberley-run, auto;
            animation-range: contain 0% contain 20.8%;
            animation-duration: auto, 700ms;
            animation-delay: 0s, 450ms;
            animation-timing-function: linear, var(--kimberley-e-quart);
            animation-fill-mode: both, backwards;
        }

        .kimberley-line {
            animation: kimberley-line-by linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 20.8% contain 43.7%;
        }

        /* Closed at 52.7%, well short of the end: the sheet has to be the whole screen with
           scroll still left, both so the ending is read at rest and so the film can spend
           its cut behind it. */
        .kimberley-sheet {
            animation: kimberley-sheet-over linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 44% contain 46.4%;
        }

        /* Out of their own baselines, the way the wordmark came out of the floor. The
           first one starts before the sheet has finished so the two read as one arrival
           rather than two beats. The sweep fills forwards only, so the rise keeps the
           transform until the sweep's own range opens. */
        /* Panel one is the only one that rises: the second is already made when it
           arrives, and all of its motion is lateral. */
        .kimberley-panel-one .kimberley-close-in {
            animation: kimberley-close-up linear both;
            animation-timeline: --kimberley-run;
        }

        .kimberley-close-line:nth-of-type(1) .kimberley-close-in { animation-range: contain 46% contain 47.9%; }
        .kimberley-close-line:nth-of-type(2) .kimberley-close-in { animation-range: contain 47.2% contain 49.1%; }
        .kimberley-close-line:nth-of-type(3) .kimberley-close-in { animation-range: contain 48.4% contain 50.3%; }

        /* The rule draws once the three lines have all landed. */
        .kimberley-close-ruled::after {
            animation: kimberley-rule-in linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 50.7% contain 52%;
        }

        /* Then the same hand writes the ampersand: the roman letter leaves as the nib lays
           the italic one down over it. One animation each rather than a list of ranges on one. */
        .kimberley-amp {
            animation: kimberley-amp-off linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 52.4% contain 54.2%;
        }

        .kimberley-amp-nib {
            animation: kimberley-amp-write linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 52.4% contain 59.5%;
        }

        /* The panels move by the line, never as a block: the inner span carries the arrival
           and the line itself carries the departure, so each is staggered on its own clock.
           The two overlap, so one is still peeling off while the other is coming in. */
        .kimberley-panel-one .kimberley-close-line {
            animation: kimberley-sweep-out linear both;
            animation-timeline: --kimberley-run;
        }

        .kimberley-panel-one .kimberley-close-line:nth-of-type(1) { animation-range: contain 64% contain 73%; }
        .kimberley-panel-one .kimberley-close-line:nth-of-type(2) { animation-range: contain 65.5% contain 74.5%; }
        .kimberley-panel-one .kimberley-close-line:nth-of-type(3) { animation-range: contain 67% contain 76%; }

        .kimberley-thread {
            animation: kimberley-thread-turn linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 63% contain 78%;
        }

        /* The pen carries on: it leaves the ampersand and draws the curve under the block,
           which is why this opens on the beat the ink lands rather than with the paragraph. */
        .kimberley-thread path {
            animation: kimberley-thread-draw linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 59.5% contain 88%;
        }

        .kimberley-ground {
            animation: kimberley-ground-turn linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 62% contain 73%;
        }

        .kimberley-panel-two {
            transform: none;
        }

        /* A word at a time, 0.9% apart, the way the first panel's lines arrive. Each word
           carries its own range inline. */
        .kimberley-lead-word {
            animation: kimberley-lead-in linear both;
            animation-timeline: --kimberley-run;
        }

        .kimberley-panel-one .kimberley-note {
            animation: kimberley-note-up linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 58% contain 66%;
        }

        /* The later name in a list wins a property while it runs, and no part of the
           opening fills forwards, so the scroll animation takes each element back.
           The word, the dots and the aperture keep their own percentages; ranging them
           into the first 26.5% leaves the line, the sheet and the ending the rest. */
        .kimberley-wordmark {
            animation-name: kimberley-sink, kimberley-rise;
            animation-timeline: --kimberley-run, auto;
            animation-range: contain 0% contain 20.8%;
            animation-duration: auto, 750ms;
            animation-delay: 0s, 1000ms;
            animation-timing-function: linear, var(--kimberley-e-quart);
            animation-fill-mode: both, backwards;
        }

        .kimberley-dot {
            animation-timeline: --kimberley-run, auto;
            animation-range: contain 0% contain 20.8%;
            animation-duration: auto, 1700ms;
            animation-timing-function: linear, linear;
            animation-fill-mode: both, none;
        }

        .kimberley-dot-one { animation-name: kimberley-gather-one, kimberley-seed-one; }
        .kimberley-dot-two { animation-name: kimberley-gather-two, kimberley-seed-two; }

        .kimberley-window {
            animation: kimberley-aperture linear both;
            animation-timeline: --kimberley-run;
            animation-range: contain 0% contain 20.8%;
        }
    }
}
