/* ==========================================================================
   Site background: a drifting gradient mesh
   Five wide, soft colour fields on near black, each blended with screen and
   drifting on its own long, deliberately unrelated period, so the composition
   never lands in the same place twice. Shared by the home and every page built
   on the app layout (sign in, legal, account, store and the rest), so they all
   sit on the same background. Everything animates by transform alone, which is
   a cheap compositor step; nothing re-rasterises per frame.
   ========================================================================== */

.mesh {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    background: linear-gradient(180deg, #03040a 0%, #020308 55%, #010205 100%);
}

/* Vignette: pulls the edges down so the content keeps the eye in the middle. */
.mesh::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at center, transparent 30%, rgba(0, 0, 0, 0.8) 100%);
}

/* The mesh is a positioned layer at z-index 0, so anything that should sit on
   top of it has to be positioned too: a static element paints underneath a
   positioned one regardless of document order. The navbar already carries its
   own z-index; the main content and the footer are lifted here. */
main,
.footer {
    position: relative;
    z-index: 1;
}

/* A wide blur on five large layers is the whole cost of this background, so the
   radius is kept modest: still soft to the eye, far cheaper to draw. */
.mesh__blob {
    position: absolute;
    border-radius: 50%;
    mix-blend-mode: screen;
    filter: blur(56px);
    will-change: transform;
}

.mesh__blob--1 {
    top: -32%;
    left: -22%;
    width: 92vmax;
    height: 70vmax;
    background: radial-gradient(ellipse, rgba(21, 103, 245, 0.26), transparent 66%);
    animation: mesh-drift-1 19s ease-in-out infinite;
}

.mesh__blob--2 {
    top: -14%;
    right: -26%;
    width: 74vmax;
    height: 88vmax;
    background: radial-gradient(ellipse, rgba(53, 182, 255, 0.2), transparent 66%);
    animation: mesh-drift-2 23s ease-in-out infinite;
}

.mesh__blob--3 {
    bottom: -34%;
    left: 6%;
    width: 100vmax;
    height: 66vmax;
    background: radial-gradient(ellipse, rgba(94, 132, 196, 0.15), transparent 64%);
    animation: mesh-drift-3 29s ease-in-out infinite;
}

.mesh__blob--4 {
    right: -18%;
    bottom: -26%;
    width: 84vmax;
    height: 82vmax;
    background: radial-gradient(ellipse, rgba(16, 38, 92, 0.34), transparent 68%);
    animation: mesh-drift-4 31s ease-in-out infinite;
}

.mesh__blob--5 {
    top: 16%;
    left: 22%;
    width: 70vmax;
    height: 58vmax;
    background: radial-gradient(ellipse, rgba(150, 198, 255, 0.08), transparent 62%);
    animation: mesh-drift-5 37s ease-in-out infinite;
}

/* Translate only. Rotating or scaling a blurred layer forces the browser to
   re-render the whole blur every frame; moving a layer that is already
   rasterised is nearly free, so the drift stays and the jank goes. */
@keyframes mesh-drift-1 {
    33% { transform: translate(30%, 26%); }
    66% { transform: translate(12%, 40%); }
}

@keyframes mesh-drift-2 {
    33% { transform: translate(-32%, 28%); }
    66% { transform: translate(-46%, 6%); }
}

@keyframes mesh-drift-3 {
    33% { transform: translate(26%, -30%); }
    66% { transform: translate(-16%, -14%); }
}

@keyframes mesh-drift-4 {
    33% { transform: translate(-34%, -28%); }
    66% { transform: translate(-10%, -42%); }
}

@keyframes mesh-drift-5 {
    33% { transform: translate(-30%, 30%); }
    66% { transform: translate(26%, 18%); }
}

/* On phones the blobs hold still: the gradient looks the same, but the GPU
   rasterises each blurred layer once instead of animating it. */
@media (max-width: 768px) {
    .mesh__blob {
        animation: none;
        will-change: auto;
    }
}

/* ------------------------------------------------------------ light mode -- */

/* The same drifting field, turned for a light page: an off-white with a hint of
   blue instead of pure white, pale brand blues that tint the page (multiply)
   rather than light it up (screen), and a faint blue edge in place of the dark
   vignette. The palette is set once as custom properties; the explicit light
   theme and the system preference both switch to it. */
.mesh {
    --mesh-light-base: linear-gradient(180deg, #f5f8fe 0%, #eef3fc 55%, #e9effa 100%);
    --mesh-light-edge: radial-gradient(ellipse at center, transparent 45%, rgba(120, 150, 210, 0.16) 100%);
    --mesh-light-1: radial-gradient(ellipse, rgba(21, 103, 245, 0.16), transparent 66%);
    --mesh-light-2: radial-gradient(ellipse, rgba(53, 182, 255, 0.18), transparent 66%);
    --mesh-light-3: radial-gradient(ellipse, rgba(120, 150, 230, 0.14), transparent 64%);
    --mesh-light-4: radial-gradient(ellipse, rgba(99, 102, 241, 0.1), transparent 68%);
    --mesh-light-5: radial-gradient(ellipse, rgba(56, 189, 248, 0.12), transparent 62%);
}

[data-theme="light"] .mesh { background: var(--mesh-light-base); }
[data-theme="light"] .mesh::after { background: var(--mesh-light-edge); }
[data-theme="light"] .mesh__blob { mix-blend-mode: multiply; }
[data-theme="light"] .mesh__blob--1 { background: var(--mesh-light-1); }
[data-theme="light"] .mesh__blob--2 { background: var(--mesh-light-2); }
[data-theme="light"] .mesh__blob--3 { background: var(--mesh-light-3); }
[data-theme="light"] .mesh__blob--4 { background: var(--mesh-light-4); }
[data-theme="light"] .mesh__blob--5 { background: var(--mesh-light-5); }

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) .mesh { background: var(--mesh-light-base); }
    :root:not([data-theme="dark"]) .mesh::after { background: var(--mesh-light-edge); }
    :root:not([data-theme="dark"]) .mesh__blob { mix-blend-mode: multiply; }
    :root:not([data-theme="dark"]) .mesh__blob--1 { background: var(--mesh-light-1); }
    :root:not([data-theme="dark"]) .mesh__blob--2 { background: var(--mesh-light-2); }
    :root:not([data-theme="dark"]) .mesh__blob--3 { background: var(--mesh-light-3); }
    :root:not([data-theme="dark"]) .mesh__blob--4 { background: var(--mesh-light-4); }
    :root:not([data-theme="dark"]) .mesh__blob--5 { background: var(--mesh-light-5); }
}

@media (prefers-reduced-motion: reduce) {
    .mesh__blob { animation: none; }
}
