/* ==========================================================================
   Poyon.be - single page stylesheet

   The logo ships as two transparent pieces (mascot + wordmark) so they can be
   laid out independently: side by side on wide screens, stacked on narrow ones.

   The background is a deep blue-to-violet gradient lit by three drifting orbs.
   Each orb wanders on its own path: the element carries the horizontal travel,
   its ::before carries the vertical one, and the six periods are pairwise
   coprime so the combined motion never settles into a visible loop.

   Speed is calibrated, not guessed. These gradients are very diffuse, so slow
   travel produces no perceptible change. Measure the mean per-second colour
   change averaged over many phases -- sampling two fixed instants lands on a
   random point of the ease curve and overstates it. First version: 0.97 RGB
   units per second, at the threshold of perception, and it read as a still
   image. Second: 2.34, still too slow. Current: 6.0.

   To retune, divide all six periods by the same factor and keep them pairwise
   coprime, so the combined pattern stays non-repeating (currently 25 hours).
   ========================================================================== */

:root {
    /* Gradient palette */
    --deep:    #061436;
    --blue:    #0d3a8c;
    --indigo:  #2a2496;
    --violet:  #4a239b;

    --orb-violet: rgba(122, 58, 205, 0.62);
    --orb-blue:   rgba(38, 120, 235, 0.58);
    --orb-deep:   rgba(16, 32, 110, 0.70);
    --pool:       rgba(2, 6, 24, 0.62);

    /* The mascot drives the scale; the wordmark follows the ratio of the
       original artwork (583px tall vs 160px). */
    --mascot-height:   clamp(160px, 24vw, 280px);
    --wordmark-height: calc(var(--mascot-height) / 3.65);
    --lockup-gap:      clamp(1.25rem, 4vw, 3rem);
}

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

html,
body {
    height: 100%;
}

body {
    margin: 0;
    font-family: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    color: #eaf1ff;
    background-color: var(--deep);
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   Animated background
   -------------------------------------------------------------------------- */
.backdrop {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    background: linear-gradient(132deg,
                var(--deep)   0%,
                var(--blue)  34%,
                var(--indigo) 68%,
                var(--violet) 100%);
}

/* Vignette, above the orbs: keeps the corners deep whatever drifts past. */
.backdrop::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(78% 68% at 50% 46%,
                transparent 42%, rgba(3, 8, 28, 0.55) 100%);
}

.orb {
    position: absolute;
    display: block;
    will-change: transform;
}

/* The orb element travels horizontally, its ::before vertically. */
.orb::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    will-change: transform;
}

.orb--violet {
    top: -28%;
    left: 42%;
    width: 92vmax;
    height: 84vmax;
    animation: wander-x 5s ease-in-out infinite alternate;
}

.orb--violet::before {
    background: radial-gradient(closest-side, var(--orb-violet) 0%, transparent 100%);
    animation: wander-y 7s ease-in-out infinite alternate;
}

.orb--blue {
    top: -6%;
    left: -22%;
    width: 88vmax;
    height: 78vmax;
    animation: wander-x 6s ease-in-out infinite alternate-reverse;
}

.orb--blue::before {
    background: radial-gradient(closest-side, var(--orb-blue) 0%, transparent 100%);
    animation: wander-y 11s ease-in-out infinite alternate;
}

.orb--deep {
    top: 48%;
    left: 8%;
    width: 100vmax;
    height: 72vmax;
    animation: wander-x 9s ease-in-out infinite alternate;
}

.orb--deep::before {
    background: radial-gradient(closest-side, var(--orb-deep) 0%, transparent 100%);
    animation: wander-y 13s ease-in-out infinite alternate-reverse;
}

@keyframes wander-x {
    from { transform: translate3d(-42%, 0, 0); }
    to   { transform: translate3d(42%, 0, 0); }
}

@keyframes wander-y {
    from { transform: translate3d(0, -38%, 0); }
    to   { transform: translate3d(0, 38%, 0); }
}

/* --------------------------------------------------------------------------
   Layout: full-viewport centering (horizontal + vertical)
   -------------------------------------------------------------------------- */
.stage {
    position: relative;
    z-index: 1;           /* own stacking context, above .backdrop */
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    min-height: 100dvh;
    padding: 2rem;
}

.lockup {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--lockup-gap);
}

/* Pool of shade behind the logo, painted above the orbs but below the images.
   The wordmark is mid-blue on a blue ground, so brightening here would push the
   two closer together: measured on the real assets, a light halo drops contrast
   to 1.6:1 while this darker pool lifts it to about 4.1:1. It travels with the
   logo, so a passing orb never washes the wordmark out. */
.lockup::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 260%;
    height: 215%;
    transform: translate(-50%, -50%);
    z-index: -1;
    pointer-events: none;
    /* Spread wide with a long tail: a tighter pool reads as a visible dark
       oval, and costs only 0.13 of contrast to soften. */
    background: radial-gradient(50% 50% at 50% 50%,
                var(--pool) 0%,
                rgba(2, 6, 24, 0.38) 50%,
                rgba(2, 6, 24, 0.13) 72%,
                transparent 90%);
}

.lockup picture {
    display: block;
}

.lockup img {
    display: block;
    width: auto;
    max-width: 100%;
}

.lockup__mascot img {
    height: var(--mascot-height);
    filter: drop-shadow(0 20px 30px rgba(2, 8, 30, 0.65));
    animation: rise-left 900ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.lockup__wordmark img {
    height: var(--wordmark-height);
    /* Two shadows: a light one to detach the blue from the blue ground,
       a dark one to give the lockup depth. */
    filter: drop-shadow(0 0 14px rgba(120, 200, 255, 0.45))
            drop-shadow(0 12px 22px rgba(2, 8, 30, 0.55));
    animation: rise-right 900ms cubic-bezier(0.22, 1, 0.36, 1) 130ms both;
}

@keyframes rise-left {
    from { opacity: 0; transform: translate3d(-20px, 12px, 0); }
    to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes rise-right {
    from { opacity: 0; transform: translate3d(20px, 12px, 0); }
    to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* Narrow screens: stack the two pieces */
@media (max-width: 620px) {
    :root {
        --mascot-height: clamp(150px, 38vw, 220px);
        --lockup-gap: 1.5rem;
    }

    .stage {
        padding: 1.25rem;
    }

    .lockup {
        flex-direction: column;
    }

    .lockup::before {
        width: 200%;
        height: 150%;
    }

    .lockup__wordmark img {
        height: auto;
        width: min(78vw, 340px);
    }
}

/* Accessibility */
@media (prefers-reduced-motion: reduce) {
    .orb,
    .orb::before,
    .lockup__mascot img,
    .lockup__wordmark img {
        animation: none;
    }
}
