/* =============================================================================================
   The room of every page (draft "Tropfen 3", 2026-10-23): the fixed layer with the far dust and the
   tints of the worlds, two depths of dust that follow the scroll (welcome/js/room.js, Parallax), and
   the stage of the light being in document space. Moved from welcome/tropfen.css unchanged, so the
   subpages share it; markup from site_room.php (SiteRoom). Additions at the end: pages with the
   room (.has-room) and the calm room of the legal texts.
   ============================================================================================= */

/* --- The room: tints of the current world and dust in three depths ------------------------- */

/* The far dust is part of the room's own background: it would hardly move with the scroll, and as
   a layer of its own it would only add a screen of blending to every frame. */
.room {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: clip;
    pointer-events: none;
    background:
        radial-gradient(circle at 12% 18%, rgba(214, 224, 240, 0.385) 0 0.7px, transparent 1.4px) 0 0 / 380px 380px,
        radial-gradient(circle at 37% 64%, rgba(214, 224, 240, 0.315) 0 0.6px, transparent 1.3px) 0 0 / 380px 380px,
        radial-gradient(circle at 58% 31%, rgba(214, 224, 240, 0.35) 0 0.7px, transparent 1.4px) 0 0 / 380px 380px,
        radial-gradient(circle at 81% 77%, rgba(214, 224, 240, 0.28) 0 0.6px, transparent 1.3px) 0 0 / 380px 380px,
        radial-gradient(circle at 92% 12%, rgba(214, 224, 240, 0.315) 0 0.7px, transparent 1.4px) 0 0 / 380px 380px,
        radial-gradient(circle at 24% 88%, rgba(214, 224, 240, 0.245) 0 0.6px, transparent 1.3px) 0 0 / 380px 380px,
        radial-gradient(circle at 68% 52%, rgba(214, 224, 240, 0.21) 0 0.5px, transparent 1.2px) 0 0 / 380px 380px,
        radial-gradient(circle at 46% 9%, rgba(214, 224, 240, 0.245) 0 0.6px, transparent 1.3px) 0 0 / 380px 380px,
        radial-gradient(90vmax 70vmax at 50% -10%, rgba(30, 38, 52, 0.55), transparent 70%);
}

.room-tint {
    --tint: var(--w-pearl);

    position: absolute;
    inset: -20vmax;
    background:
        radial-gradient(48vmax 40vmax at 70% 44%, color-mix(in oklab, var(--tint) var(--tint-near, 15%), transparent), transparent 72%),
        radial-gradient(42vmax 34vmax at 30% 86%, color-mix(in oklab, var(--tint) var(--tint-far, 6%), transparent), transparent 70%);
    opacity: 0;
    transition: opacity 2.2s var(--ease-in-out), transform 2.6s var(--ease-in-out);
}

/* Calm (the legal texts, Maurice 2026-10-23: "Animationen und Design leicht gedämpft"): only the
   far dust (site_room.php leaves the near depths out), softer tints that change more slowly. */
.room--calm .room-tint {
    --tint-near: 7%;
    --tint-far: 3%;

    transition-duration: 3.2s;
}

.room-tint[data-tint="web"] { --tint: var(--w-web); }
.room-tint[data-tint="software"] { --tint: var(--w-software); }
.room-tint[data-tint="ai"] { --tint: var(--w-ai); }
.room-tint[data-tint="trading"] { --tint: var(--w-trading); }
.room-tint[data-tint="apps"] { --tint: var(--w-apps); }
.room-tint[data-tint="games"] { --tint: var(--w-games); }
.room-tint[data-tint="care"] { --tint: var(--w-care); }

/* The world in view tints the room; between two worlds both fade, so their colours mix. */
.room:not([data-world]) .room-tint[data-tint="pearl"],
.room[data-world="pearl"] .room-tint[data-tint="pearl"],
.room[data-world="web"] .room-tint[data-tint="web"],
.room[data-world="software"] .room-tint[data-tint="software"],
.room[data-world="ai"] .room-tint[data-tint="ai"],
.room[data-world="trading"] .room-tint[data-tint="trading"],
.room[data-world="apps"] .room-tint[data-tint="apps"],
.room[data-world="games"] .room-tint[data-tint="games"],
.room[data-world="care"] .room-tint[data-tint="care"],
.room[data-world="mix"] .room-tint[data-tint="care"],
.room[data-world="mix"] .room-tint[data-tint="software"] {
    opacity: 1;
}

/* The glow stands on the side of the drop in view. */
.room[data-side="left"] .room-tint {
    transform: translateX(-42vw);
}

.dust {
    --par: 0.04;

    position: absolute;
    inset: -12vh 0 auto;
    height: calc(124vh + var(--range, 0px) * var(--par));
    will-change: transform;
}

.dust i {
    position: absolute;
    inset: 0;
    background-repeat: repeat;
}

.dust--mid {
    --par: 0.08;
}

.dust--mid i {
    background-image:
        radial-gradient(circle at 18% 26%, rgba(226, 232, 244, 0.42) 0 1px, transparent 2px),
        radial-gradient(circle at 63% 71%, rgba(226, 232, 244, 0.36) 0 1px, transparent 2px),
        radial-gradient(circle at 84% 34%, rgba(226, 232, 244, 0.3) 0 0.9px, transparent 1.9px),
        radial-gradient(circle at 39% 91%, rgba(226, 232, 244, 0.28) 0 0.9px, transparent 1.9px),
        radial-gradient(circle at 7% 62%, rgba(226, 232, 244, 0.3) 0 1px, transparent 2px);
    background-size: 600px 600px;
    background-position: 140px 60px;
}

.dust--near {
    --par: 0.15;
}

.dust--near i {
    background-image:
        radial-gradient(circle at 22% 38%, rgba(236, 240, 248, 0.24) 0 1.6px, transparent 3.4px),
        radial-gradient(circle at 74% 16%, rgba(236, 240, 248, 0.2) 0 1.4px, transparent 3.2px),
        radial-gradient(circle at 56% 82%, rgba(236, 240, 248, 0.18) 0 1.8px, transparent 3.8px);
    background-size: 900px 900px;
    background-position: -220px 300px;
}

/* Mid and near depth follow the scroll at their own depth (start.js, Parallax): one transform per
   layer and frame, written only while the page moves. Since Tropfen 3 no scroll-driven animation:
   held at rest by DepthHold, it was released a frame late and the near dust jumped (Maurice, 2026-10-21). */

/* --- The stage of the light being (document space, moves with the page) --------------------- */

/* The being swims above the pictures and below every text and control: on its ways it may pass
   behind a line, it never covers one. */
.stage {
    position: absolute;
    inset: 0;
    z-index: 2;
    overflow: clip;
    pointer-events: none;
}

.being {
    position: absolute;
    top: 0;
    left: 0;
    contain: strict;
    will-change: transform;
}

.being canvas {
    display: block;
    width: 100%;
    height: 100%;
}

/* --- Pages with the room (the subpages) ------------------------------------------------------ */

/* Main and footer stand above the room, every part of main above the stage of the being: on its
   ways it may pass behind a line, it never covers one. */
.has-room main,
.has-room .site-footer {
    position: relative;
    z-index: 1;
}

.has-room main > :not(.stage) {
    position: relative;
    z-index: 3;
}

/* --- Flights through the room (welcome/js/voyage.js, glide.js fly(), warp.js) ------------------ */

/* Maurice, 2026-10-23: "vorwärts durch den Space reisen und dann dort landen", within the home page
   and between the pages. The page (main and the footer) flies, moved by the script (transform and
   opacity only); the room stays behind it, and the streaks of light run on a canvas between the
   room and the page, there only during a flight. */
.warp {
    position: fixed;
    inset: 0;
    z-index: 0;
    display: none;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.warp.is-on {
    display: block;
}

/* While it flies the page takes no pointer (a press ends an in-page flight and goes on to its
   control, Scroller.handOn); header and ring stay usable. The near dust rests in the light of the
   streaks: its parallax would jump with the scroll. A landing page stays usable. */
html.is-flying main,
html.is-flying .site-footer {
    pointer-events: none;
    will-change: transform, opacity;
}

html.is-landing main,
html.is-landing .site-footer {
    will-change: transform, opacity;
}

/* A flying page grows past the edges of the window: the body clips it. With the root clipping as
   well, the body keeps its own clip instead of handing it to the viewport. Without this the layout
   viewport of a phone grew with the page (430 to 499 px wide during a departure, measured), fixed
   bars widened, and the browser aborted the cross-document transition ("Viewport size changed"). */
html.is-flying,
html.is-landing,
html.is-flying body,
html.is-landing body {
    overflow-x: clip;
}

.room .dust {
    transition: opacity 0.6s ease 0.15s;
}

html.is-flying .room .dust {
    opacity: 0;
    transition-duration: 0.25s;
    transition-delay: 0s;
}

/* Arriving by a flight (html.voyage-in, set by the inline script in <head> before the first
   picture): the content waits out of sight until it lands (voyage.js), 3 s at the most. In a
   cross-document view transition the old page's last picture flies on above the new page, whose
   room and streaks already run: after 0.15 s (the new page's light comes on meanwhile) it grows past
   the reader and fades in 0.4 s like the page itself (voyage.js departure). Both pictures blend
   normally (the browser would add them: a bright frame). */
html.voyage-in main,
html.voyage-in .site-footer {
    opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
    html.voyage-in::view-transition-old(root) {
        z-index: 1;
        mix-blend-mode: normal;
        animation: voyage-away 0.4s cubic-bezier(0.4, 0, 0.75, 0.45) 0.15s both;
    }

    html.voyage-in::view-transition-new(root) {
        mix-blend-mode: normal;
        animation: none;
    }
}

@keyframes voyage-away {
    40% {
        opacity: 0.88;
    }

    100% {
        opacity: 0;
        transform: scale(1.32);
    }
}
