/* ===========================================================================
   Butterfly.

   A wireframe moth-thing drifting through the sheet. It is drawn in the same
   language as the rest of the site — hairline strokes, barely-there fill — so
   it reads as part of the drawing rather than a sticker dropped on top of it.

   It flies *behind* the text and above the backdrop. That is the whole reason
   it works: this layout has wide empty margins, so the butterfly is visible
   almost all the time, but it passes behind anything you might be reading and
   never competes with a word.

   The light it carries is the interesting part. `mix-blend-mode` means the glow
   is not a disc laid over the page — it combines with the grid and the stars
   underneath, so those actually brighten as it passes:

     screen   on the blueprint — it is luminous, and lifts what is beneath it
     multiply on paper         — a real butterfly over a sheet casts a shadow,
                                 it does not glow, so on the light theme the
                                 same element softly darkens instead

   That one swap is what stops the light theme looking like a mistake.
   =========================================================================== */

.fly-field {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    contain: strict;
}

/* --- the light it casts --------------------------------------------------- */

.fly-glow {
    position: absolute;
    top: 0;
    left: 0;
    width: 330px;
    height: 330px;
    margin: -165px 0 0 -165px;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 50%,
        color-mix(in srgb, var(--accent) 34%, transparent) 0%,
        color-mix(in srgb, var(--accent) 12%, transparent) 32%,
        transparent 68%);
    mix-blend-mode: multiply;
    opacity: .5;
    will-change: transform;
}

@media (prefers-color-scheme: dark) {
    .fly-glow {
        mix-blend-mode: screen;
        opacity: .85;
    }
}

/* --- the wake ------------------------------------------------------------- */

/* Sampled positions from a few frames ago, fading out. Gives the flight a
   direction you can read even when the butterfly is momentarily still. */
.fly-wake {
    position: absolute;
    top: 0;
    left: 0;
    width: 3px;
    height: 3px;
    margin: -1.5px 0 0 -1.5px;
    border-radius: 50%;
    background: var(--accent);
    opacity: 0;
    will-change: transform, opacity;
}

/* --- the butterfly -------------------------------------------------------- */

/* `perspective` here is what makes the wings genuinely three-dimensional
   rather than a squash. Each wing is a real plane hinged on the body axis and
   turned out of the page; the foreshortening you see is the projection doing
   the work, which is why the leading edge shortens faster than the trailing
   one. A `scaleX` fake cannot do that — it compresses every point equally, and
   the eye reads it as a shutter closing instead of a wing lifting. */
.fly {
    position: absolute;
    top: 0;
    left: 0;
    width: 74px;
    height: 74px;
    margin: -37px 0 0 -37px;
    perspective: 190px;
    will-change: transform;
}

/* The airframe. Carries heading, pitch, roll and depth; the wings hang off it
   and inherit all of that for free. */
.fly-craft {
    position: absolute;
    inset: 0;
    transform-style: preserve-3d;
    will-change: transform;
}

.fly-wing {
    position: absolute;
    top: 0;
    height: 100%;
    width: 50%;
    transform-style: preserve-3d;
    will-change: transform;
}

/* Both wings hinge on the body's centre line, so each one's origin is its own
   inner edge. */
.fly-wing-l {
    left: 0;
    transform-origin: 100% 50%;
    animation: fly-flap-l .42s cubic-bezier(.33, 0, .3, 1) infinite alternate;
}

.fly-wing-r {
    left: 50%;
    transform-origin: 0 50%;
    animation: fly-flap-r .42s cubic-bezier(.33, 0, .3, 1) infinite alternate;
}

.fly-wing svg,
.fly-torso {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.fly-torso {
    position: absolute;
    top: 0;
    left: 0;
}

.fly-shape {
    fill: color-mix(in srgb, var(--accent) 13%, transparent);
    stroke: var(--accent);
    stroke-width: 2.4;
    stroke-linejoin: round;
}

.fly-vein {
    fill: none;
    stroke: var(--accent);
    stroke-width: 1.2;
    opacity: .5;
}

.fly-body {
    fill: none;
    stroke: var(--accent);
    stroke-width: 2.6;
    stroke-linecap: round;
}

/* Opposite signs: mirrored hinges mean the same sign would swing the two wings
   in opposite directions in world space. Stopping a little short of flat at the
   open end keeps a shallow dihedral, which is what stops a butterfly at rest
   looking like a pressed specimen. */
@keyframes fly-flap-l {
    from { transform: rotateY(-8deg); }
    to   { transform: rotateY(-74deg); }
}

@keyframes fly-flap-r {
    from { transform: rotateY(8deg); }
    to   { transform: rotateY(74deg); }
}

/* ---------------------------------------------------------------------------
   Off switch.

   A thing that moves on its own, forever, is the single most disruptive item
   on this page for anyone sensitive to motion. It goes away completely.
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .fly-field { display: none; }
}
