
    .preloader.svelte-16ylr1u {
        --bg-color: var(--lib-control-bg);
        --loader-stroke-width: 0.125rem;
        --loader-stroke-border-width: 0;
        --loader-bg-color: var(--lib-control-border-subtle);
        --loader-filled-color: var(--lib-control-color-action);

        /* Overlay, not a page: the configurator mounts underneath as soon as its data
           arrives (so the 3D app can start loading) and stays covered until it reports
           ready. Above all app chrome (max 4000), below the debugger. */
        position: fixed;
        inset: 0;
        z-index: 5000;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2.5rem;
        padding: 1.25rem;
        box-sizing: border-box;
        background-color: var(--bg-color);
        color: var(--lib-control-text-secondary);

        .loader:where(.svelte-16ylr1u) {
            --loader-progress: conic-gradient(
                from 0,
                var(--loader-filled-color) var(--radial-degree),
                var(--loader-bg-color) var(--radial-degree)
            );

            position: relative;
            border-radius: 50%;
            width: min(2rem, 100%);
            aspect-ratio: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 1rem;
            background: var(--loader-progress);
            padding: var(--loader-stroke-width);
            border: var(--loader-stroke-border-width) solid var(--loader-bg-color);

            /* The ring itself cannot animate during startup: a conic-gradient repaint needs the
               main thread, and hydration plus the 3D boot saturate it, so the fill sits frozen
               until it snaps at a milestone. This arc rides the same band on a transform-only
               animation, which Chromium runs on the compositor — it keeps turning through the
               freeze, so the page reads as working rather than stuck. */
            .spinner:where(.svelte-16ylr1u) {
                position: absolute;
                inset: 0;
                box-sizing: border-box;
                border-radius: 50%;
                border: var(--loader-stroke-width) solid transparent;
                border-top-color: var(--loader-filled-color);
                animation: svelte-16ylr1u-spin 1s linear infinite;
                will-change: transform;
            }

            .loader-content:where(.svelte-16ylr1u) {
                width: 100%;
                aspect-ratio: 1;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                background-color: var(--bg-color);
                border: var(--loader-stroke-border-width) solid var(--loader-bg-color);
                box-sizing: border-box;
            }
        }

        .logo:where(.svelte-16ylr1u) {
            width: min(10rem, 100%);
            max-height: 10rem;
            display: flex;
            align-items: center;
            justify-content: center;

            img:where(.svelte-16ylr1u) {
                display: block;
                width: 100%;
                height: auto;
            }
        }

        .title:where(.svelte-16ylr1u) {
            font-size: 0.875rem;
            font-weight: 500;
            line-height: normal;
        }

        .subtitle:where(.svelte-16ylr1u) {
            font-size: 0.6875rem;
            font-weight: 500;
            line-height: normal;
        }
    }

    @keyframes svelte-16ylr1u-spin {
        to {
            transform: rotate(1turn);
        }
    }

    /* The ring still reports progress; only the motion goes away. */
    @media (prefers-reduced-motion: reduce) {
        .preloader.svelte-16ylr1u .spinner:where(.svelte-16ylr1u) {
            display: none;
        }
    }
