/* =====================================================================
   sky.css — the shared sky every page lives under.
   Loaded by every page together with sky/sky.js.
   ===================================================================== */

:root {
    /* all set by sky.js as you scroll */
    --sky-top:    #5fa8dc;
    --sky-bottom: #bfe3f5;
    --dusk:  0;     /* 0 in daylight → 1 once the sun is down  */
    --night: 0;     /* 0 until deep blue → 1 at midnight       */

    --ink:       #3a2716;
    --ink-faded: #6e5236;
    --sanguine:  #9a3b1f;
}

* { box-sizing: border-box; }

html { background: #5fa8dc; }

body {
    margin: 0;
    min-height: 100vh;
    padding: 96px 16px 0;
    color: var(--ink);
    font-family: "IM Fell English", Georgia, "Times New Roman", serif;
    font-size: 1.15rem;
    line-height: 1.65;
    background: transparent;
}

/* empty stretch added after each page's content, so scrolling carries the
   sky all the way to midnight (length set with <body data-voyage="…">) */
.voyage { height: 110vh; }

/* ---------- links: a little constellation traced under the words ---------- */
a {
    color: var(--sanguine);
    text-decoration: none;
    padding-bottom: 7px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='46' height='10'%3E%3Cpolyline points='1,7 10,3 21,8 32,2 45,6' fill='none' stroke='%239a3b1f' stroke-width='.7' opacity='.6'/%3E%3Cg fill='%239a3b1f'%3E%3Ccircle cx='1' cy='7' r='1'/%3E%3Ccircle cx='10' cy='3' r='1.5'/%3E%3Ccircle cx='21' cy='8' r='1.1'/%3E%3Ccircle cx='32' cy='2' r='1.7'/%3E%3Ccircle cx='45' cy='6' r='1'/%3E%3C/g%3E%3C/svg%3E") repeat-x left bottom / 46px 10px;
    transition: color .2s, text-shadow .2s;
}
a:hover {
    color: var(--ink);
    text-shadow: 0 0 6px rgba(255, 214, 140, 0.9);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='46' height='10'%3E%3Cpolyline points='1,7 10,3 21,8 32,2 45,6' fill='none' stroke='%233a2716' stroke-width='.8'/%3E%3Cg fill='%233a2716'%3E%3Ccircle cx='1' cy='7' r='1.2'/%3E%3Ccircle cx='10' cy='3' r='1.8'/%3E%3Ccircle cx='21' cy='8' r='1.3'/%3E%3Ccircle cx='32' cy='2' r='2'/%3E%3Ccircle cx='45' cy='6' r='1.2'/%3E%3C/g%3E%3C/svg%3E");
}

/* ================= backdrop ================= */
.skybox, .skybox > div { position: absolute; inset: 0; }
.skybox > div { opacity: 0; background-size: cover; background-position: center bottom; }
.skybox .skybox-tint { background: linear-gradient(to bottom, var(--sky-top), var(--sky-bottom)); mix-blend-mode: multiply; }
/* from reset 4, until there's a painted hell sky (sky.js): the sky, drawn or painted, takes on the colour of the Demiurge's
   fire (its own light and dark kept: dusk and night still come) */
.skybox .hell-veil { display: none; }
html.hell-sky .skybox .hell-veil { display: block; opacity: 1; mix-blend-mode: color;
    background: linear-gradient(to bottom, #6e0a08 0%, #a8160c 45%, #d8401a 80%, #ff7a2a 100%); }
html.hell-sky .skybox .hell-veil::after { content: ""; position: absolute; inset: 0; mix-blend-mode: multiply;
    background: linear-gradient(to bottom, rgba(90, 20, 14, .35), rgba(255, 170, 120, .15)); }
.backdrop {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    background: linear-gradient(to bottom, var(--sky-top) 0%, var(--sky-bottom) 70%);
}

.stars,
.stars::before,
.stars::after { position: absolute; inset: 0; }
.stars {
    opacity: 0;
    background-image:
        radial-gradient(1px 1px at 23px 41px,  rgba(255,255,255,.85), transparent),
        radial-gradient(1px 1px at 97px 160px, rgba(255,255,255,.6),  transparent),
        radial-gradient(1px 1px at 151px 88px, rgba(255,255,255,.75), transparent),
        radial-gradient(1px 1px at 201px 219px,rgba(255,255,255,.5),  transparent),
        radial-gradient(1px 1px at 61px 203px, rgba(255,255,255,.7),  transparent),
        radial-gradient(1px 1px at 219px 17px, rgba(255,255,255,.55), transparent);
    background-size: 240px 240px;
    -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent 78%);
            mask-image: linear-gradient(to bottom, #000 45%, transparent 78%);
}
.stars::before {
    content: "";
    background-image:
        radial-gradient(1.5px 1.5px at 44px 290px, #fff, transparent),
        radial-gradient(1.5px 1.5px at 188px 64px, rgba(255,255,255,.9), transparent),
        radial-gradient(1.5px 1.5px at 301px 177px,rgba(255,255,255,.8), transparent),
        radial-gradient(1.5px 1.5px at 260px 311px,rgba(220,230,255,.9), transparent),
        radial-gradient(1.5px 1.5px at 120px 131px,rgba(255,255,255,.7), transparent);
    background-size: 337px 337px;
    animation: twinkle 5s ease-in-out infinite alternate;
}
.stars::after {
    content: "";
    background-image:
        radial-gradient(2px 2px at 90px 70px,  rgba(255,250,235,.95), transparent),
        radial-gradient(2px 2px at 330px 260px,rgba(230,238,255,.9),  transparent),
        radial-gradient(2px 2px at 210px 390px,rgba(255,255,255,.8),  transparent),
        radial-gradient(2px 2px at 380px 40px, rgba(255,255,255,.85), transparent);
    background-size: 419px 419px;
    animation: twinkle 7s ease-in-out -3s infinite alternate;
}
@keyframes twinkle { from { opacity: .45; } to { opacity: 1; } }

/* Ursa Minor, hanging below Polaris (its viewBox is centred on Polaris) */
.ursa {
    position: absolute;
    top: 3vh;
    left: 50%;
    width: 240px;
    transform: translateX(-50%);
    opacity: 0;
    overflow: visible;
}

.sun, .moon { position: absolute; transform: translate(-50%, -50%); }
.sun {
    width: min(192px, 30vw);
    color: #f7d35e;
    filter: drop-shadow(0 3px 5px rgba(0,0,0,.25)) drop-shadow(0 0 18px rgba(255,210,120,.5));
}
.moon {
    width: min(124px, 20vw);
    color: #efe6c8;
    filter: drop-shadow(0 2px 4px rgba(0,0,0,.35)) drop-shadow(0 0 16px rgba(240,230,200,.45));
}

.cloud {
    position: absolute;
    color: #f6f1e6;
    filter: drop-shadow(0 4px 5px rgba(40,60,80,.25));
}

/* ================= Polaris: always visible, always takes you home ================= */
.polaris {
    position: fixed;
    top: calc(3vh + 2px);
    left: 50%;
    z-index: 5;
    width: 52px;
    height: 52px;
    margin-left: -26px;
    padding: 0;
    border-radius: 50%;
    background: none;
    color: #fffaf0;
    filter:
        drop-shadow(0 1px 2px rgba(20, 40, 70, calc(.5 * (1 - var(--night)))))
        drop-shadow(0 0 calc(7px * var(--night)) rgba(255, 240, 200, .9));
    transition: transform .25s;
}
.polaris svg { display: block; width: 100%; height: 100%; overflow: visible; }
.polaris .rays { stroke: currentColor; stroke-linecap: round; stroke-width: 1.2; }
.polaris .core { fill: currentColor; }

.polaris .polaris-name,
.polaris .polaris-hint {
    position: absolute;
    white-space: nowrap;
    font-style: italic;
    color: #f3e6c2;
    pointer-events: none;
}
.polaris .polaris-name {
    right: 100%;
    top: 50%;
    transform: translateY(-50%);
    margin-right: 2px;
    font-size: .95rem;
    opacity: var(--night);
}
.polaris .polaris-hint {
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    font-size: .85rem;
    color: #fff6dc;
    text-shadow: 0 1px 3px rgba(20,40,70,.6);
    opacity: 0;
    transition: opacity .25s;
}
.polaris:hover,
.polaris:focus-visible {
    color: #fffaf0;
    background: radial-gradient(circle, rgba(255,240,200,.45) 0 30%, transparent 70%);
    text-shadow: none;
    outline: none;
    transform: scale(1.12);
}
.polaris:hover .polaris-hint,
.polaris:focus-visible .polaris-hint,
.polaris.flare .polaris-hint { opacity: 1; }
/* Polaris only shows (and can be clicked) at night, like the constellations */
.polaris { pointer-events: none; }
.polaris.live { pointer-events: auto; }
.polaris.flare { animation: star-flare 2.4s ease-out; }
.polaris.flare .core { animation: star-pop .6s ease-out 2 alternate; transform-box: fill-box; transform-origin: 50% 50%; }

/* ================= constellation links in the night sky ================= */
.sky-links { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
.sky-link {
    position: absolute;
    display: block;
    width: 150px;
    padding: 0;
    background: none;
    color: #f3e6c2;
    font-style: italic;
    font-size: .95rem;
    text-align: center;
    text-decoration: none;
    opacity: 0;
    visibility: hidden;
    transition: filter .2s, color .2s;
}
.sky-links.live .sky-link { pointer-events: auto; }
.sky-link .sl-art { display: block; }
.sky-link svg, .sky-link .sl-art > .art { display: block; width: 100%; overflow: visible; }
.sky-link .sl-name { display: block; }
.sky-link .sl-note { display: block; font-size: .8rem; color: rgba(243,230,194,.75); opacity: 0; transition: opacity .25s; }
.sky-link:hover .sl-note, .sky-link:focus-visible .sl-note, .sky-link.flare .sl-note { opacity: 1; }
.sky-link.flare { animation: star-flare 2.4s ease-out; }
.sky-link.flare .st { animation: star-pop .6s ease-out 2 alternate; transform-box: fill-box; transform-origin: 50% 50%; }
@keyframes star-flare { 0% { filter: drop-shadow(0 0 2px rgba(255,240,200,.6)); } 12% { filter: drop-shadow(0 0 14px rgba(255,240,200,1)); } 100% { filter: none; } }
@keyframes star-pop { to { transform: scale(1.7); } }
.egg-star { position: fixed; z-index: 1; width: 300px; pointer-events: none; filter: drop-shadow(0 0 6px rgba(255,245,210,.9)); }
.egg-star svg { display: block; width: 100%; }
.sky-link .ln { fill: none; stroke: rgba(225,232,255,.4); stroke-width: 1; stroke-dasharray: 3 4; stroke-linecap: round; }
.sky-link .st { fill: #e8edff; }
.sky-link:hover,
.sky-link:focus-visible {
    color: #fff6dc;
    background: none;
    text-shadow: none;
    filter: drop-shadow(0 0 6px rgba(255,240,200,.9));
    outline: none;
}
.sky-link:hover .ln,
.sky-link:focus-visible .ln { stroke: rgba(255,246,220,.9); stroke-dasharray: none; }

.sky-link.l1 { left: 5vw;   top: 38vh; }
.sky-link.l2 { right: 6vw;  top: 10vh; }
.sky-link.l3 { right: 21vw; top: 36vh; }
.sky-link.l4 { left: 24vw;  top: 30vh; }
.sky-link.l5 { left: 22vw;  top: 8vh; }
.sky-link.l6 { right: 27vw; top: 14vh; }
.sky-link.l7 { left: 38vw;  top: 44vh; }
/* away from the homepage the tabs take the right edge: the constellations there shift in a little */
body:not([data-page="home"]) .sky-link.l2 { right: 11vw; }

/* ================= the place tabs (every page but the homepage) ================= */
.place-tabs {
    position: fixed;
    right: 0;
    top: 27vh;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    transition: opacity .4s, visibility 0s;
}
.place-tab {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    width: 64px;
    height: 56px;
    padding: 0 0 0 10px;
    border-radius: 14px 0 0 14px;
    overflow: hidden;
    white-space: nowrap;
    background: #eadcb9;
    color: #3a2716;
    text-decoration: none;
    font-style: italic;
    font-size: 1.05rem;
    box-shadow: -4px 5px 12px rgba(0, 0, 0, .38), inset 0 0 16px rgba(120, 80, 30, .22);
    transition: width .35s cubic-bezier(.3, .7, .3, 1), background .2s, transform .2s;
}
.place-tab .pt-pic { flex: none; display: block; width: 40px; height: 40px; }
.place-tab .pt-pic svg, .place-tab .pt-pic > .art { display: block; width: 100%; height: 100%; object-fit: contain; }
.place-tab .pt-name { opacity: 0; transition: opacity .2s; padding-right: 16px; }
/* (any tab but the one you're at: a room's tab can stop being "you are here" as you walk out of it, sky/house.js) */
.place-tab:not(.here):not(.pt-fold) { cursor: pointer; }
.place-tab:not(.here):not(.pt-fold):hover, .place-tab:not(.here):not(.pt-fold):focus-visible { width: 220px; background: #f3e8cc; outline: none; }
.place-tab:hover .pt-name, .place-tab:focus-visible .pt-name { opacity: 1; }
.place-tab.here { width: 74px; background: #3a2716; color: #f3e6c2; box-shadow: -4px 5px 12px rgba(0, 0, 0, .38), inset 4px 0 0 #9a3b1f; }
.place-tab.here .pt-pic { background: #eadcb9; border-radius: 50%; padding: 3px; box-sizing: border-box; }
.place-tab.here:hover { width: 280px; }
/* (the kitchen's tab is a link even while you're in there: it keeps the dark "you are here" look on hover, or its pale words vanish) */
a.place-tab.here:hover, a.place-tab.here:focus-visible { background: #3a2716; }
/* hidden while something is open over the page */
body.sky-view .place-tabs, body.gallery-open .place-tabs, body.records-open .place-tabs, body.crate-open .place-tabs,
body.peep-view .place-tabs, body.peep-close .place-tabs, body.art-open .place-tabs, body.visitors-open .place-tabs, body.leaving .place-tabs {
    opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .4s, visibility 0s .4s;
}
/* the place tabs on phones (5 Oct): folded away, so they don't cover the room. only "you are here" shows (or the door,
   .pt-fold, on a page that isn't a place); tapped, the rest fan out from behind it with their names (sky.js, "fold") */
.pt-fold { display: none; border: 0; font: inherit; cursor: pointer; }
@media (max-width: 620px), (max-height: 500px) {
    /* (top right, under the control panel's button: lower down, at furniture height, it covered the stove, the crate…) */
    .place-tabs { top: 140px; bottom: auto; gap: 6px; }
    .place-tab { width: 50px; height: 46px; padding-left: 8px; gap: 8px; font-size: .95rem; }
    .place-tab .pt-pic { width: 34px; height: 34px; }
    .place-tab.here { width: 58px; }
    .place-tab:not(.here):not(.pt-fold):hover, .place-tab:not(.here):not(.pt-fold):focus-visible { width: 50px; }
    .place-tab.here:hover { width: 58px; }
    .place-tab .pt-name { display: none; }
    .place-tabs:not(:has(.here)) .pt-fold { display: flex; }
    /* "you are here" (or the door) stays where it is, at the top; the others come out below it */
    .place-tab.here, .pt-fold { order: -1; cursor: pointer; }
    .place-tabs:not(.open) .place-tab:not(.here):not(.pt-fold) { display: none; }
    .place-tabs.open .place-tab:not(.here):not(.pt-fold) { width: max-content; min-width: 172px; animation: pt-fan .28s cubic-bezier(.3, .7, .3, 1) both; }
    .place-tabs.open .place-tab .pt-name { display: block; opacity: 1; }
    .place-tabs.open .place-tab.here { width: max-content; min-width: 180px; }
    .place-tabs.open .place-tab:nth-child(2) { animation-delay: .04s; }
    .place-tabs.open .place-tab:nth-child(3) { animation-delay: .08s; }
    .place-tabs.open .place-tab:nth-child(4) { animation-delay: .12s; }
    .place-tabs.open .place-tab:nth-child(5) { animation-delay: .16s; }
}
/* held sideways: a little higher, so they all fit when they're out */
@media (max-height: 500px) and (min-width: 621px) {
    .place-tabs { top: 92px; }
}
/* the homepage's signpost on phones: short planks, all of them showing (it used to peek in from the edge, its words cut
   off, until tapped; with two short signs they fit). and the constellations: only their names take a tap, so the stars
   drawn over a window, a book or a door don't swallow taps meant for the room */
@media (max-width: 620px), (max-height: 500px) {
    body .signpost { width: 158px; transform: none; cursor: auto; }      /* (body: over the "peeks in" rule further down) */
    body .signpost .plank { width: 150px; padding: 0 30px 0 18px; font-size: 1.05rem; --nail: radial-gradient(circle at 117px 50%, #2a1a0e 0 2.2px, #b08a60 2.7px 3.3px, transparent 3.9px); }
    body .signpost .plank.here { --nail: none; }
    .sky-links.live .sky-link { pointer-events: none; }
    .sky-links.live .sky-link .sl-name, .sky-links.live .sky-link .sl-note { pointer-events: auto; }
    /* (and seen through a window indoors, just to look at: in a phone's small window they crowded what stands on the sill,
       the books, the workshop's hidden key. outside, on the sea, the rooftop, the porch, they're there to tap as ever) */
    body.has-room:not(.is-outside):not(.in-porch):not(.in-front) .sky-links.live .sky-link * { pointer-events: none; }
}
@keyframes pt-fan { from { transform: translateX(100%); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .place-tabs.open .place-tab { animation: none !important; } }

/* ================= the signpost: wooden arrow planks ================= */
.signpost {
    position: fixed;
    right: 0;
    top: 27vh;
    z-index: 5;
    width: 250px;
    padding: 6px 0 10px;
    filter: drop-shadow(0 6px 5px rgba(0, 0, 0, .45));
    transition: transform .45s cubic-bezier(.3, .7, .3, 1);
}
.signpost .post { display: none; }
.signpost .plank {
    --nail: radial-gradient(circle at 173px 50%, #2a1a0e 0 2.4px, #b08a60 2.9px 3.6px, transparent 4.2px);
    --wood:
        var(--nail),
        radial-gradient(ellipse 40px 5px at 60px 62%, rgba(50, 25, 8, .35), transparent 70%),
        repeating-linear-gradient(to bottom, transparent 0 5px, rgba(60, 30, 10, .2) 5px 6px, transparent 6px 9px, rgba(255, 220, 170, .06) 9px 10px, transparent 10px 13px),
        linear-gradient(to bottom, #a4744a 0%, #86583a 55%, #6d4628 100%);
    position: relative;
    display: block;
    width: 232px;
    height: 44px;
    margin: 0 0 12px auto;
    padding: 0 34px 0 20px;
    background: none;
    background-image: var(--wood);
    clip-path: polygon(0 4%, calc(100% - 26px) 0, 100% 50%, calc(100% - 26px) 100%, 0 96%, 7px 50%);
    color: #f6e7c4;
    font-size: 1.12rem;
    font-style: italic;
    line-height: 44px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-decoration: none;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, .6), 0 1px 0 rgba(255, 230, 190, .22);   /* carved into the wood */
    transform: rotate(var(--tilt, 0deg));
    transition: transform .25s ease, filter .25s ease;
}
.signpost a.plank:hover,
.signpost a.plank:focus-visible {
    color: #fff4d8;
    background-image: var(--wood);
    text-shadow: 0 -1px 0 rgba(0, 0, 0, .6), 0 0 8px rgba(255, 220, 150, .6);
    filter: brightness(1.12);
    transform: translateX(-5px) rotate(0deg);
    outline: none;
}
.signpost .plank.here {
    --nail: radial-gradient(circle at 163px 50%, #2a1a0e 0 2.4px, #b08a60 2.9px 3.6px, transparent 4.2px);
    --wood:
        var(--nail),
        repeating-linear-gradient(to bottom, transparent 0 5px, rgba(60, 30, 10, .22) 5px 6px, transparent 6px 13px),
        linear-gradient(to bottom, #6f5038 0%, #5a3f2a 100%);
    color: #d9c6a0;
    cursor: default;
    transform: translateX(10px) rotate(var(--tilt, 0deg));
}
/* a red-chalk mark on the sign you're standing at */
.signpost .plank.here::before {
    content: "";
    position: absolute;
    left: 10px;
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -3px;
    border-radius: 50%;
    background: var(--sanguine);
    box-shadow: 0 0 0 2px rgba(154, 59, 31, .35);
}
.signpost .plank.here span { padding-left: 6px; }

/* away from the homepage's dock there's no post: the planks sit on the screen edge as tabs */
body:not([data-page="home"]) .signpost .plank { --nail: none; }
body:not([data-page="home"]) .signpost { filter: drop-shadow(-2px 5px 5px rgba(0, 0, 0, .45)); }

/* when a scene plays a send-off (the ship sailing away), the page's paper fades out of its way */
body.leaving .letters,
body.leaving .credit { opacity: 0; transition: opacity .7s ease; }

/* one plank since 11 Oct ("visit home"): on a big screen it hangs lower, so its post on the dock (sky/ground-sea.js,
   drawn up to wherever the sign is) is shorter */
@media (min-width: 1101px) and (min-height: 501px) {
    body[data-page="home"] .signpost { top: 50vh; }
}
/* narrow screens: the signpost peeks in from the edge until tapped */
@media (max-width: 1100px) {
    .signpost { transform: translateX(178px); cursor: pointer; }
    .signpost.open { transform: none; }
}

/* ================= grounds (sea, countryside, city …) ================= */
.ground {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    pointer-events: none;
    overflow-x: clip;
    overflow-y: visible;
}
.ground .layer {
    position: absolute;
    left: -6%;
    bottom: -12px;
    width: 112%;
    height: calc(100% + 12px);
    overflow: hidden;
}

/* ================= rooms: an interior wall with a window onto the sky ================= */
.room {
    position: fixed;
    inset: 0;
    z-index: 3;
    overflow: hidden;
    pointer-events: none;
    --wall:  #6e4e36;
    --frame: #3b2618;
    transition: transform .9s cubic-bezier(.55, 0, .25, 1), opacity .6s ease .25s, visibility 0s;
}
.room > * { pointer-events: auto; }

/* the window: its giant shadow paints the wall everywhere except the glass */
.room .window {
    position: absolute;
    z-index: 0;
    display: block;
    padding: 0;
    border: 12px solid var(--frame);
    border-radius: 3px;
    cursor: zoom-in;
    background:
        linear-gradient(var(--frame), var(--frame)) center / 7px 100% no-repeat,
        linear-gradient(var(--frame), var(--frame)) center / 100% 7px no-repeat,
        linear-gradient(135deg, rgba(255,255,255,.14) 0 18%, transparent 18% 30%, rgba(255,255,255,.08) 30% 36%, transparent 36%);
    box-shadow:
        0 0 0 300vmax var(--wall),
        inset 0 0 22px rgba(0,0,0,.35);
}
.room .window:hover {
    text-shadow: none;
    background:
        linear-gradient(var(--frame), var(--frame)) center / 7px 100% no-repeat,
        linear-gradient(var(--frame), var(--frame)) center / 100% 7px no-repeat,
        linear-gradient(135deg, rgba(255,255,255,.26) 0 18%, transparent 18% 30%, rgba(255,255,255,.16) 30% 36%, transparent 36%);
}
/* window sill */
.room .window::after {
    content: "";
    position: absolute;
    left: -26px;
    right: -26px;
    bottom: -30px;
    height: 16px;
    border-radius: 2px;
    background: var(--frame);
    box-shadow: 0 6px 8px rgba(0,0,0,.35);
}

/* plank texture + evening dimming over the wall (the window is cut out of it) */
.room::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        radial-gradient(ellipse at var(--lamp-x, 20%) var(--lamp-y, 40%), rgba(255, 200, 120, calc(.22 * var(--dusk))), transparent 45%),
        linear-gradient(rgba(10, 14, 30, calc(.45 * var(--dusk))), rgba(10, 14, 30, calc(.45 * var(--dusk)))),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.14 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
        repeating-linear-gradient(to right, transparent 0 118px, rgba(0,0,0,.18) 118px 120px, rgba(255,255,255,.04) 120px 122px);
    -webkit-mask:
        linear-gradient(#000 0 0),
        linear-gradient(#000 0 0) var(--wx, -999px) var(--wy, -999px) / var(--ww, 0) var(--wh, 0) no-repeat;
    -webkit-mask-composite: xor;
            mask:
        linear-gradient(#000 0 0),
        linear-gradient(#000 0 0) var(--wx, -999px) var(--wy, -999px) / var(--ww, 0) var(--wh, 0) no-repeat;
            mask-composite: exclude;
}
.room .furnish { position: absolute; z-index: 2; }

/* the floor: from the very bottom of the screen up to --floor-h, with a skirting board along the top.
   your own art: assets/<place>/floor (stretched to fit). */
.room .room-floor {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: var(--floor-h, 9vh);
    min-height: 34px;
    z-index: 2;              /* over the wallpaper, under the furniture (it's the room's first child) */
    pointer-events: none;
}
.room .room-floor .placeholder,
.room .room-floor > .art { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: fill; }
.room .room-floor .placeholder {
    border-top: 9px solid var(--skirting, var(--frame));
    box-shadow: 0 -3px 8px rgba(0,0,0,.28);
    background:
        linear-gradient(rgba(10, 14, 30, calc(.45 * var(--dusk))), rgba(10, 14, 30, calc(.45 * var(--dusk)))),
        linear-gradient(rgba(0,0,0,.28), transparent 40%),
        repeating-linear-gradient(to bottom, transparent 0 13px, rgba(0,0,0,.28) 13px 15px),
        repeating-linear-gradient(to right, transparent 0 158px, rgba(0,0,0,.2) 158px 160px),
        var(--floor, #2c1e14);
}
.room .room-floor > .art { z-index: 1; }

/* while you're indoors, the constellations you can see through the glass can still be clicked */
body.has-room:not(.is-outside) .sky-links {
    z-index: 4;
    clip-path: inset(var(--wy) calc(100% - var(--wx) - var(--ww)) calc(100% - var(--wy) - var(--wh)) var(--wx));
}

/* while you're indoors, the ground rises so its horizon shows in the bottom of the window */
.ground { transition: transform .9s cubic-bezier(.55, 0, .25, 1); }
body.has-room:not(.is-outside) .ground {
    transform: translateY(calc(-1 * var(--win-lift, 0px) + var(--win-sink, 50%)));
}

/* stepping outside: the room swings past you and falls away */
.room.outside {
    transform: scale(3.2);
    opacity: 0;
    visibility: hidden;
    transition: transform .9s cubic-bezier(.55, 0, .25, 1), opacity .5s ease .25s, visibility 0s .9s;
}

.back-inside {
    position: fixed;
    left: 18px;
    top: 18px;
    z-index: 6;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px 8px 10px;
    border: 0;
    border-radius: 999px;
    background: rgba(40, 28, 18, .72);
    color: #f3e6c2;
    font: italic 1rem "IM Fell English", Georgia, serif;
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: opacity .4s .6s, transform .4s .6s, visibility 0s 1s, background .2s;
}
.back-inside .bi-ic { display: inline-block; width: 22px; height: 22px; }
.back-inside svg, .back-inside .bi-ic > .art { width: 22px; height: 22px; display: block; object-fit: contain; }
.back-inside:hover { background: rgba(40, 28, 18, .9); }
body.sky-view .back-inside {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity .4s .6s, transform .4s .6s, visibility 0s .6s, background .2s;
}

/* ---------- small screens ---------- */
@media (max-width: 620px) {
    body { padding: 90px 12px 0; font-size: 1.05rem; }
    .hide-small { display: none; }
    .sky-link { width: 104px; font-size: .85rem; }
    .sky-link.l1 { left: 4vw;  top: 44vh; }
    .sky-link.l2 { right: 16vw; top: 30vh; }
    .sky-link.l3 { left: 36vw; top: 55vh; right: auto; }
    .sky-link.l4 { right: 16vw; top: 45vh; left: auto; }
    .sky-link.l5 { left: 6vw;   top: 20vh; }
    .sky-link.l6 { right: 6vw;  top: 17vh; left: auto; }
    .sky-link.l7 { left: 30vw;  top: 66vh; }
    body:not([data-page="home"]) .sky-link.l2 { right: 18vw; }
    .signpost { top: 17vh; }
    .room .window { border-width: 9px; }
}

@media (prefers-reduced-motion: reduce) {
    .stars::before, .stars::after { animation: none; }
    .room, .room.outside { transition: opacity .3s, visibility 0s .3s; transform: none; }
}

/* =====================================================================
   the sky view: a window, a telescope … anything that lets you look up
   ===================================================================== */

/* the page's paper and props step aside while you look at the sky */
.letters, .credit, .telescope { transition: opacity .6s ease, visibility 0s; }
body.sky-view .letters,
body.sky-view .credit,
body.sky-view .telescope,
body.sky-view .scene-character {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .6s ease, visibility 0s .6s;
}

/* ---------- the day/night player ---------- */
.sky-player {
    position: fixed;
    left: 50%;
    bottom: 22px;
    z-index: 7;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 16px 6px 6px;
    border-radius: 999px;
    background: #eadcb9;
    box-shadow: 0 8px 18px rgba(0, 0, 0, .45), inset 0 0 18px rgba(120, 80, 30, .25);
    color: var(--ink);
    font-style: italic;
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, 16px);
    transition: opacity .4s ease, transform .4s ease, visibility 0s .4s;
}
body.sky-view .sky-player {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition: opacity .5s ease .9s, transform .5s ease .9s, visibility 0s .9s;
}
.sky-player button {
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}
.sky-player .sp-play {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--ink);
    color: #f3e6c2;
    transition: background .2s;
}
.sky-player .sp-play:hover { background: var(--sanguine); }
.sky-player .sp-play svg { width: 18px; height: 18px; fill: currentColor; }
.sky-player .i-pause,
.sky-player.playing .i-play { display: none; }
.sky-player.playing .i-pause { display: block; }
.sky-player .sp-speeds { display: flex; gap: 2px; margin-left: 4px; }
.sky-player .sp-speeds button {
    position: relative;
    padding: 6px 9px;
    border-radius: 999px;
    color: var(--ink-faded);
    font-size: 1rem;
}
.sky-player .sp-speeds button:hover { color: var(--ink); background: rgba(110, 82, 54, .12); }
.sky-player .sp-speeds button[aria-pressed="true"] { color: var(--ink); }
.sky-player .sp-speeds button[aria-pressed="true"]::after {           /* a red-chalk dot under the chosen speed */
    content: "";
    position: absolute;
    left: 50%;
    bottom: 1px;
    width: 5px;
    height: 5px;
    margin-left: -2.5px;
    border-radius: 50%;
    background: var(--sanguine);
}
.sky-player .sp-time {
    min-width: 6.5em;
    padding-left: 10px;
    border-left: 1px solid rgba(110, 82, 54, .35);
    color: var(--ink-faded);
    font-size: .95rem;
    white-space: nowrap;
}

/* ---------- the telescope's lens ---------- */
.scope-lens {
    position: fixed;
    inset: 0;
    z-index: 4;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    --r: min(45vh, 46vw);
    background:
        radial-gradient(circle at 50% 48%,
            transparent 0 calc(var(--r) - 2px),
            #6b4a22 calc(var(--r) - 1px) var(--r),
            #c49a52 calc(var(--r) + 1px) calc(var(--r) + 6px),
            #5a3c1a calc(var(--r) + 7px) calc(var(--r) + 10px),
            rgba(6, 8, 16, .97) calc(var(--r) + 11px));
    transition: opacity .8s ease, visibility 0s .8s;
}
.scope-lens::after {                   /* faint crosshair etched on the glass */
    content: "";
    position: absolute;
    left: 50%;
    top: 48%;
    width: calc(var(--r) * 2);
    height: calc(var(--r) * 2);
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background:
        linear-gradient(rgba(255, 246, 220, .12), rgba(255, 246, 220, .12)) center / 1px 100% no-repeat,
        linear-gradient(rgba(255, 246, 220, .12), rgba(255, 246, 220, .12)) center / 100% 1px no-repeat,
        radial-gradient(circle at 35% 30%, rgba(255, 255, 255, .06), transparent 45%);
}
body.scope-view .scope-lens { opacity: 1; visibility: visible; transition: opacity 1s ease .2s; }

/* through the lens, the constellations gather inside the circle and stay clickable */
body.scope-view .sky-links { z-index: 4; clip-path: circle(min(45vh, 46vw) at 50% 48%); }
body.scope-view .sky-link.l1 { left: calc(50% - 300px); right: auto; top: 44vh; }
body.scope-view .sky-link.l2 { left: calc(50% + 120px); right: auto; top: 24vh; }
body.scope-view .sky-link.l3 { left: calc(50% + 110px); right: auto; top: 56vh; }
body.scope-view .sky-link.l4 { left: calc(50% - 250px); right: auto; top: 66vh; }
body.scope-view .sky-link.l5 { left: calc(50% - 230px); right: auto; top: 18vh; }
body.scope-view .sky-link.l6 { left: calc(50% + 150px); right: auto; top: 40vh; }
body.scope-view .sky-link.l7 { left: calc(50% - 70px);  right: auto; top: 76vh; }

/* ---------- the telescope itself (city) ---------- */
.telescope {
    position: fixed;
    left: 5vw;
    bottom: 6vh;
    z-index: 2;
    width: 190px;
    padding: 0;
    border: 0;
    background: none;
    cursor: zoom-in;
    filter: drop-shadow(0 6px 6px rgba(0, 0, 0, .4));
    transition: transform .25s ease, filter .25s ease, opacity .6s ease;
}
.telescope svg, .telescope img { display: block; width: 100%; height: auto; }
.telescope:hover { transform: rotate(-2deg) translateY(-3px); filter: drop-shadow(0 8px 8px rgba(0, 0, 0, .45)) brightness(1.08); }
.telescope .hint {
    position: absolute;
    left: 50%;
    bottom: 100%;
    transform: translateX(-50%);
    white-space: nowrap;
    font-style: italic;
    font-size: .95rem;
    color: #fdf8ec;
    text-shadow: 0 1px 4px rgba(20, 40, 60, .7);
    opacity: 0;
    transition: opacity .25s;
}
.telescope:hover .hint, .telescope:focus-visible .hint { opacity: 1; }

/* =====================================================================
   characters (placeholders until assets/characters/<scene> exists)
   ===================================================================== */
/* how tall the traveller stands in the house's rooms (27 Sep: the top of their head just under the hallway's
   doors, whose tops are 69vh - 12px up; they stand at 3vh). every room's traveller uses it, so they're one size everywhere */
:root {
    --traveller-h: calc(60vh - 11px);
}
/* (a phone held sideways, 5 Oct: a little shorter, the screen being so short: they stood in front of the dungeon's pictures) */
@media (max-height: 500px) and (min-width: 621px) {
    :root {
        --traveller-h: calc(52vh - 11px);
    }
}
@media (max-width: 620px) {
    :root {
        /* (5 Oct: and no taller than 70% of the screen's width: on an upright phone 44vh made them as tall as the screen is
           wide, standing in front of the pinboard, the oven, the sink, everything) */
        --traveller-h: calc(min(44vh, 70vw) - 11px);
    }
}
.character {
    position: absolute;
    height: 120px;
    cursor: pointer;
    filter: drop-shadow(0 4px 4px rgba(0, 0, 0, .35));
    -webkit-tap-highlight-color: transparent;
}
.character .placeholder,
.character .art { display: block; height: 100%; width: auto; }
/* only the traveller themselves takes a click, not the see-through box round them (they're tall now: they stand in front of
   things, the record player, the bookshelf, and those must still be clickable round them). the drawn stand-in: exactly its
   shape; your own picture: its box, as ever */
.character { pointer-events: none; }
.character > img, .character > .art { pointer-events: auto; }
.character svg { pointer-events: none; }
.character svg * { pointer-events: visiblePainted; }
.character .art.glow-layer { position: absolute; left: 0; top: 0; opacity: var(--dusk); }
.character:focus-visible { outline: 2px dashed #fff6dc; outline-offset: 4px; }

.bubble {
    position: absolute;
    left: 50%;
    bottom: calc(100% + 12px);
    z-index: 3;
    max-width: 220px;
    width: max-content;
    padding: 8px 14px;
    border-radius: 14px;
    background: #f3e8cc;
    color: var(--ink);
    font-size: 1rem;
    font-style: italic;
    line-height: 1.35;
    text-align: center;
    box-shadow: 0 5px 10px rgba(0, 0, 0, .3), inset 0 0 12px rgba(120, 80, 30, .18);
    opacity: 0;
    transform: translate(-50%, 6px) scale(.9);
    transform-origin: 50% 100%;
    pointer-events: none;
    transition: opacity .25s ease, transform .25s ease;
}
.bubble::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 100%;
    margin-left: -8px;
    border: 8px solid transparent;
    border-top-color: #f3e8cc;
}
.character.talking .bubble { opacity: 1; transform: translate(-50%, 0) scale(1); }

/* an asset that has a -glow twin: the twin fades in at dusk */
img.glow-layer { opacity: var(--dusk); pointer-events: none; }
img.furnish { object-fit: contain; object-position: 50% 100%; }

@media (max-width: 620px) {
    .sky-player { gap: 2px; padding-right: 10px; }
    .sky-player .sp-time { display: none; }
    .sky-player .sp-speeds button { padding: 6px 7px; }
    .telescope { width: 120px; left: 3vw; }
    body.scope-view .sky-link { width: 96px; }
    body.scope-view .sky-link.l1 { left: calc(50% - 150px); top: 40vh; }
    body.scope-view .sky-link.l2 { left: calc(50% + 30px);  top: 34vh; }
    body.scope-view .sky-link.l3 { left: calc(50% + 10px);  top: 50vh; }
    body.scope-view .sky-link.l4 { left: calc(50% - 130px); top: 56vh; }
    body.scope-view .sky-link.l5 { left: calc(50% - 120px); top: 26vh; }
    body.scope-view .sky-link.l6 { left: calc(50% + 20px);  top: 22vh; }
    body.scope-view .sky-link.l7 { left: calc(50% - 50px);  top: 64vh; }
}

/* characters on the move: facing and a little walking bob */
.character.face-left .placeholder,
.character.face-left .art { transform: scaleX(-1); }
.character.walking .placeholder,
.character.walking .art { animation: char-step .32s ease-in-out infinite alternate; }
.character.walking.face-left .placeholder,
.character.walking.face-left .art { animation-name: char-step-left; }
@keyframes char-step      { from { transform: translateY(0) rotate(-2deg); }            to { transform: translateY(-4px) rotate(2deg); } }
@keyframes char-step-left { from { transform: scaleX(-1) translateY(0) rotate(-2deg); } to { transform: scaleX(-1) translateY(-4px) rotate(2deg); } }
@media (prefers-reduced-motion: reduce) { .character.walking .placeholder, .character.walking .art { animation: none; } }
@media (max-width: 620px) {
    /* on phones the exit button sits just above the player, clear of Polaris */
    .back-inside { top: auto; bottom: 84px; left: 50%; transform: translate(-50%, 8px); }
    body.sky-view .back-inside { transform: translate(-50%, 0); }
}

/* =====================================================================
   the home button: a compass by day, Polaris by night
   ===================================================================== */
.polaris .p-star    { opacity: var(--night); transition: opacity .3s; }
.polaris .needle  { transform-box: fill-box; transform-origin: 50% 50%; animation: needle 6s ease-in-out infinite alternate; }
@keyframes needle { 0% { transform: rotate(-7deg); } 60% { transform: rotate(5deg); } 100% { transform: rotate(-2deg); } }
.polaris:hover .needle { animation-duration: 1.2s; }
@media (prefers-reduced-motion: reduce) { .polaris .needle { animation: none; } }

/* while the day/night loop plays, Polaris is just a star in the sky:
   it can't be clicked, and it comes and goes with the night */
body.sky-playing .polaris { pointer-events: none; }
body.sky-playing .polaris .p-compass,
body.sky-playing .polaris .polaris-hint { opacity: 0; }
body.sky-playing .polaris .p-star { opacity: var(--night); }
body.sky-playing .polaris .polaris-name { opacity: var(--night); }
body.sky-playing .polaris { filter: drop-shadow(0 0 calc(7px * var(--night)) rgba(255, 240, 200, .9)); }

/* =====================================================================
   interface buttons (the city's telescope)
   ===================================================================== */
.ui-button {
    position: fixed;
    left: 18px;
    bottom: 18px;
    z-index: 6;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 16px 6px 6px;
    border: 0;
    border-radius: 999px;
    background: #eadcb9;
    color: var(--ink);
    font: italic 1.05rem "IM Fell English", Georgia, serif;
    box-shadow: 0 8px 18px rgba(0, 0, 0, .4), inset 0 0 18px rgba(120, 80, 30, .25);
    cursor: pointer;
    transition: transform .2s ease, box-shadow .2s ease, opacity .5s ease, visibility 0s;
}
.ui-button .ui-icon {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--ink);
    color: #f3e6c2;
    overflow: hidden;
    transition: background .2s;
}
.ui-button .ui-icon svg, .ui-button .ui-icon img { width: 26px; height: 26px; display: block; object-fit: contain; }
.ui-button:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(0, 0, 0, .45), inset 0 0 18px rgba(120, 80, 30, .25); }
.ui-button:hover .ui-icon { background: var(--sanguine); }
body.sky-view .ui-button { opacity: 0; visibility: hidden; transition: opacity .4s ease, visibility 0s .4s; }

/* looking through the telescope: the ground drops away and the sky draws closer */
.backdrop { transition: transform 1.6s cubic-bezier(.3, .6, .2, 1); transform-origin: 50% calc(3vh + 28px); }
body.scope-view .backdrop { transform: scale(1.3); }
.ground { transition: transform .9s cubic-bezier(.55, 0, .25, 1), opacity .9s ease; }
body.scope-view .ground { transform: translateY(110%); opacity: 0; }

/* character poses: <name>-held.gif replaces the picture while they're picked up */
.character .pose { display: none; height: 100%; width: auto; }
.character.has-held.held .pose-held { display: block; }
.character.has-held.held > .placeholder,
.character.has-held.held > .art { display: none; }
/* with a struggling GIF of your own, the site stops doing its own wiggle */
.character.has-held.held .pose-held { animation: none !important; transform: none; }
.character.has-held.held.face-left .pose-held { transform: scaleX(-1); }
.character.has-startled.startled .pose-startled { display: block; }
.character.has-startled.startled > .placeholder,
.character.has-startled.startled > .art { display: none; }
.character.has-startled.startled.face-left .pose-startled { transform: scaleX(-1); }
.character.has-walking.walking .pose-walking { display: block; animation: none !important; }
.character.has-walking.walking > .placeholder,
.character.has-walking.walking > .art { display: none; }
.character.has-walking.walking.face-left .pose-walking { transform: scaleX(-1); }

/* =====================================================================
   your art in the slots (see assets/README.txt)
   ===================================================================== */
.sun .placeholder, .moon .placeholder, .cloud .placeholder,
.sun > .art, .moon > .art, .cloud > .art { display: block; width: 100%; height: auto; }
.sun > .glow-layer, .moon > .glow-layer, .cloud > .glow-layer { position: absolute; left: 0; top: 0; }
.sun.has-art, .moon.has-art { filter: none; }
.cloud.has-art { filter: none; }

.polaris .p-compass, .polaris .p-star { position: absolute; inset: 0; display: block; }
.polaris .p-compass > .art, .polaris .p-star > .art { display: block; width: 100%; height: 100%; object-fit: contain; }

.signpost.has-plank-art .plank,
.signpost.has-plank-art a.plank:hover,
.signpost.has-plank-art a.plank:focus-visible { background: var(--plank-art) center / 100% 100% no-repeat; clip-path: none; }
.signpost.has-plank-art .plank.here { background-image: var(--plank-here-art, var(--plank-art)); filter: brightness(.82); }

.room.has-wall::before {
    background:
        radial-gradient(ellipse at var(--lamp-x, 20%) var(--lamp-y, 40%), rgba(255, 200, 120, calc(.22 * var(--dusk))), transparent 45%),
        linear-gradient(rgba(10, 14, 30, calc(.45 * var(--dusk))), rgba(10, 14, 30, calc(.45 * var(--dusk)))),
        var(--wall-art) center / cover no-repeat;
}
.room.has-wall::after { display: none; }
.room .window.has-art { border-color: transparent; background: none; }
.room .window.has-art::after { display: none; }
.room .window > .art { position: absolute; left: -12px; top: -12px; width: calc(100% + 24px); height: calc(100% + 24px); object-fit: fill; pointer-events: none; }
/* a cork of your own still spins about its own middle when it's pulled */
svg[data-bottle] .b-cork.has-art { transform-box: view-box; transform-origin: 177px 45px; }
/* a layer of scenery replaced by your picture: the drawing hides, the picture dims at night,
   and its -glow twin (lit windows, lamps) fades in */
.layer.has-art > :not(.layer-art):not(defs) { display: none; }
.layer .layer-art .art:not(.glow-layer) { filter: brightness(calc(1 - .55 * var(--dusk))) saturate(calc(1 - .3 * var(--dusk))); }
.layer .layer-art .glow-layer { opacity: var(--dusk); }

/* =====================================================================
   things that fly across the sky in the sky view (slots: assets/sky/blimp, birds,
   balloon, shooting-star; see FLYERS near the top of sky.js)
   ===================================================================== */
.flyers { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.flyer { position: absolute; left: 0; top: 0; visibility: hidden; will-change: transform; }
.flyer.flying { visibility: visible; }
.flyer .placeholder, .flyer > .art { display: block; width: 100%; height: auto; }
.flyer > .glow-layer { position: absolute; left: 0; top: 0; opacity: var(--dusk); }
.flyer-blimp, .flyer-balloon, .flyer-birds { filter: brightness(calc(1 - .55 * var(--dusk))) drop-shadow(0 4px 5px rgba(0,0,0,.25)); }
.flyer-blimp .glow-bits { opacity: calc(.25 + .75 * var(--dusk)); }
.flyer-blimp .prop { animation: blimp-prop .18s linear infinite; }
@keyframes blimp-prop { from { transform: scaleY(1); } 50% { transform: scaleY(.15); } to { transform: scaleY(1); } }
.flyer-birds .wing { transform-box: fill-box; transform-origin: 50% 60%; animation: bird-flap .5s ease-in-out infinite alternate; }
@keyframes bird-flap { from { transform: scaleY(1); } to { transform: scaleY(-.55); } }
.flyer-shooting-star { filter: drop-shadow(0 0 6px rgba(255,245,210,.9)); }
@media (prefers-reduced-motion: reduce) { .flyer-blimp .prop, .flyer-birds .wing { animation: none; } }


/* ================= the see-through arrows between places (the living space's side rooms, the way back from the workshop) ================= */
.room-arrow, .room-arrow:hover { padding: 0; background: none; text-shadow: none; }
.room-arrow { position: fixed; z-index: 5; width: 54px; height: 54px; display: block; opacity: .5; transition: opacity .25s, transform .25s, visibility 0s;
    filter: drop-shadow(0 2px 4px rgba(0,0,0,.45)); -webkit-tap-highlight-color: transparent; }
.room-arrow:hover, .room-arrow:focus-visible { opacity: 1; transform: translateX(4px); outline: none; }
.room-arrow > svg, .room-arrow > .art { display: block; width: 100%; height: 100%; object-fit: contain; }
.room-arrow.point-left > svg, .room-arrow.point-left > .art { transform: scaleX(-1); }
.room-arrow.point-left:hover, .room-arrow.point-left:focus-visible { transform: translateX(-4px); }
.room-arrow .ra-hint { position: absolute; top: 50%; transform: translateY(-50%); white-space: nowrap; font-style: italic; font-size: .95rem; color: #f3e6c2;
    text-shadow: 0 1px 3px rgba(0,0,0,.8); opacity: 0; transition: opacity .25s; pointer-events: none; }
.room-arrow.point-left .ra-hint { left: calc(100% + 8px); }
.room-arrow:not(.point-left) .ra-hint { right: calc(100% + 8px); }
.room-arrow:hover .ra-hint, .room-arrow:focus-visible .ra-hint { opacity: 1; }
body.leaving .room-arrow, body.sky-view .room-arrow, body.is-outside .room-arrow, body.gallery-open .room-arrow, body.art-open .room-arrow,
body.visitors-open .room-arrow, body.frame-open .room-arrow, body.model-open .room-arrow, body.notes-open .room-arrow, body.paint-open .room-arrow {
    opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .3s, visibility 0s .3s; }

/* the living space's side rooms wait off either edge (hidden) from the very first frame; sky/bathroom.js slides them in */
.bathroom, .hallway, .dungeon { position: fixed; inset: 0; z-index: 3; overflow: hidden; visibility: hidden; }
.dungeon { transform: translateY(100%); }
.bathroom { transform: translateX(100%); }
.hallway { transform: translateX(-100%); }

/* Polaris shows only where you'd really see it: outdoors on the homepage, or out through
   a window or the telescope (the sky view). indoors, and on the rooftop at a glance, it's hidden. */
body:not([data-page=home]):not(.sky-view) .polaris { opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; }

/* ================= a reset's own sun (sky/state.js: assets/resets/reset-<n>/sky/sun): twice the size ================= */
.sun:has(> img[src*="assets/resets/"]) { width: min(384px, 60vw); }

/* ================= a painted sky, mirrored in the morning ================= */
/* the golden, sunset and dusk skies are painted with the sun going down on the right; while it's
   on the left (coming up), they're flipped to match (sky.js adds .mirror) */
.skybox.mirror > [data-sky=golden], .skybox.mirror > [data-sky=sunset], .skybox.mirror > [data-sky=dusk] { transform: scaleX(-1); }

/* ================= props on ropes: the sky's a stage set (resets 1 and 2 only: sky/state.js) =================
   each prop hangs on a rope from the flies: the rope runs down behind it and ends out of sight behind its
   middle (so it's never seen stopping short in mid-air). your own rope: assets/sky/rope, a short piece
   hanging straight down that repeats along its length (sky.js sets --rope-art). and, like any flat prop in
   front of a painted backdrop, each one throws a shadow onto the sky behind it, lit from the front and above. */
:root { --stage-shadow: 14px 19px 7px rgba(22, 13, 5, calc(.46 - .16 * var(--dusk, 0))); --rope-w: 5px; }
@media (max-width: 620px) { :root { --stage-shadow: 8px 11px 5px rgba(22, 13, 5, calc(.34 - .14 * var(--dusk, 0))); --rope-w: 3.5px; } }
html.stage-strings .sun::before, html.stage-strings .moon::before,
html.stage-strings .cloud::before, html.stage-strings .cloud::after,
html.stage-strings .flyer-blimp::before, html.stage-strings .flyer-blimp::after,
html.stage-strings .flyer-balloon::before, html.stage-strings .flyer-birds::before {
    content: ""; position: absolute; z-index: -1; left: 50%; bottom: 50%; width: var(--rope-w); height: 300vh; margin-left: calc(var(--rope-w) / -2); pointer-events: none;
    /* the drawn rope: twisted strands, rounded by the light */
    background:
        linear-gradient(90deg, rgba(0,0,0,.38), rgba(0,0,0,0) 38%, rgba(255,236,200,.22) 52%, rgba(0,0,0,.42)),
        repeating-linear-gradient(-58deg, #5b4229 0 1.6px, #8d6c45 1.6px 3.6px, #6e5234 3.6px 5.2px);
    box-shadow: var(--stage-shadow);
    filter: brightness(calc(1 - .45 * var(--dusk, 0)));
}
html.stage-strings.has-rope-art .sun::before, html.stage-strings.has-rope-art .moon::before,
html.stage-strings.has-rope-art .cloud::before, html.stage-strings.has-rope-art .cloud::after,
html.stage-strings.has-rope-art .flyer-blimp::before, html.stage-strings.has-rope-art .flyer-blimp::after,
html.stage-strings.has-rope-art .flyer-balloon::before, html.stage-strings.has-rope-art .flyer-birds::before {
    background: var(--rope-art) center bottom / 100% auto repeat-y;
}
/* where each rope ties on (its bottom end, tucked behind the prop) */
html.stage-strings .moon::before { left: 27%; }                 /* (onto the crescent itself, not the empty middle) */
html.stage-strings .cloud::before { left: 30%; bottom: 40%; }
html.stage-strings .cloud::after { left: 70%; bottom: 40%; }
html.stage-strings .flyer-blimp::before { left: 32%; bottom: 60%; }
html.stage-strings .flyer-blimp::after { left: 68%; bottom: 60%; }
html.stage-strings .flyer-balloon::before { bottom: 62%; }
html.stage-strings .flyer-birds::before { bottom: 55%; }
/* and they swing (sky/ropes.js sets --rope-a, and moves the prop sideways): each rope tilts about where it's tied,
   and the sun and moon, each on one rope, tilt with theirs (--prop-tilt) */
html.stage-strings :is(.sun, .moon, .cloud, .flyer-blimp, .flyer-balloon, .flyer-birds)::before,
html.stage-strings :is(.cloud, .flyer-blimp)::after { transform: rotate(var(--rope-a, 0rad)); transform-origin: 50% 100%; }
html.stage-strings :is(.sun, .moon) > * { rotate: var(--prop-tilt, 0rad); }
html.stage-strings .moon > * { transform-origin: 27% 50%; }
/* the shadows the props throw on the backdrop (the flyers already have a filter of their own: it's added to) */
html.stage-strings :is(.sun, .moon, .cloud) > :is(.art:not(.glow-layer), .placeholder) { filter: drop-shadow(var(--stage-shadow)); }
/* with your picture (and its -glow twin fading in over it at dusk), the shadow's cast by the prop as a whole: one shadow
   of whatever's showing, rope and all, so it can't flicker between the two pictures as they play (a GIF each) */
html.stage-strings :is(.sun, .moon, .cloud).has-art { filter: drop-shadow(var(--stage-shadow)); }
html.stage-strings :is(.sun, .moon, .cloud).has-art > .art { filter: none; }
html.stage-strings :is(.sun, .moon, .cloud).has-art::before,
html.stage-strings :is(.sun, .moon, .cloud).has-art::after { box-shadow: none; }
html.stage-strings :is(.flyer-blimp, .flyer-balloon, .flyer-birds) { filter: brightness(calc(1 - .55 * var(--dusk))) drop-shadow(var(--stage-shadow)); }
html.stage-strings :is(.flyer-blimp, .flyer-balloon, .flyer-birds)::before,
html.stage-strings :is(.flyer-blimp, .flyer-balloon, .flyer-birds)::after { box-shadow: none; }      /* (their shadow comes with the rest of them) */

/* ================= a picture, not a page of text =================
   a double-click or a drag doesn't highlight things like text (or bring up the browser's little
   pop-up menu for the "selected text"), and pictures don't come loose to be dragged about.
   anywhere you type still works as usual. */
html { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
input, textarea, select, [contenteditable]:not([contenteditable=false]), [contenteditable]:not([contenteditable=false]) * { -webkit-user-select: text; user-select: text; }
img, svg, a { -webkit-user-drag: none; }

/* the traveller's words, in a box near the top (Sky.speak, sky/sky.js) (where it can't cover the traveller, or what they're doing) */
.mc-say {
    position: fixed;
    left: 50%;
    top: max(76px, 9vh);
    z-index: 9;
    transform: translateX(-50%);
    width: min(560px, 90vw);
    padding: 14px 22px 16px;
    border-radius: 6px;
    background: rgba(20, 14, 10, .92);
    border: 1px solid rgba(243, 230, 194, .35);
    box-shadow: 0 12px 30px rgba(0, 0, 0, .6);
    color: #f3e6c2;
    font: italic 1.12rem/1.5 "IM Fell English", Georgia, serif;
    opacity: 0;
    transition: opacity .35s;
    cursor: pointer;
}
.mc-say.on {
    opacity: 1;
}
.mc-say b {
    display: block;
    margin-bottom: 4px;
    font: normal .85rem "IM Fell English SC", Georgia, serif;
    letter-spacing: .06em;
    color: #c49a52;
}

/* ?slots on any page's address: every slot outlined (pink: a stand-in, green: your art's in), and a list of them (sky.js showSlots) */
body.show-slots [data-asset], body.show-slots [data-slot] { outline: 2px dashed rgba(255, 70, 140, .9); outline-offset: 2px; }
body.show-slots .has-art[data-asset], body.show-slots .has-art[data-slot] { outline-color: rgba(60, 220, 140, .95); }
.slot-panel { position: fixed; left: 12px; bottom: 12px; z-index: 50; max-height: 60vh; overflow: auto; padding: 10px 14px; border-radius: 8px;
    background: rgba(20, 16, 12, .92); color: #f3e6c2; font: 13px/1.5 ui-monospace, Menlo, monospace; box-shadow: 0 6px 20px rgba(0, 0, 0, .5); }
.slot-panel b { display: block; font: italic 15px Georgia, serif; margin-bottom: 4px; }
.slot-panel .on { color: #7fe0a8; }
.slot-panel .off { color: #c9b89a; opacity: .8; }

/* ---------- a click (11 Oct: cursors animated when clicking) ----------
   sky.js swaps every cursor for its pressed twin while the button's down, and leaves this burst of ink where the click
   lands: a ring opening out and six little strokes flying off it (or your assets/ui/click, shown once and faded) */
.click-ink {
    position: fixed;
    z-index: 2147483600;
    width: 0;
    height: 0;
    pointer-events: none;
}
.click-ink>b {
    position: absolute;
    left: -9px;
    top: -9px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid rgba(42, 29, 20, .75);
    box-shadow: 0 0 0 1px rgba(243, 230, 194, .55);
    animation: ink-ring .42s cubic-bezier(.2, .7, .3, 1) forwards;
}
.click-ink>i {
    position: absolute;
    left: -1px;
    top: -6px;
    width: 2px;
    height: 6px;
    border-radius: 1px;
    background: #2a1d14;
    box-shadow: 0 0 0 1px rgba(243, 230, 194, .45);
    transform-origin: 1px 6px;
    animation: ink-fly .4s cubic-bezier(.2, .7, .3, 1) forwards;
}
.click-ink>i:nth-child(1) { --a: 0deg; }
.click-ink>i:nth-child(2) { --a: 60deg; }
.click-ink>i:nth-child(3) { --a: 120deg; }
.click-ink>i:nth-child(4) { --a: 180deg; }
.click-ink>i:nth-child(5) { --a: 240deg; }
.click-ink>i:nth-child(6) { --a: 300deg; }
.click-ink.has-art>img {
    position: absolute;
    left: 0;
    top: 0;
    width: 40px;
    height: 40px;
    translate: -50% -50%;
    animation: ink-art .5s ease-out forwards;
}
@keyframes ink-ring {
    from { transform: scale(.2); opacity: 1; }
    to { transform: scale(1.5); opacity: 0; }
}
@keyframes ink-fly {
    from { transform: rotate(var(--a)) translateY(-4px) scaleY(.4); opacity: 1; }
    to { transform: rotate(var(--a)) translateY(-15px) scaleY(1); opacity: 0; }
}
@keyframes ink-art {
    from { scale: .6; opacity: 1; }
    70% { opacity: 1; }
    to { scale: 1.1; opacity: 0; }
}

/* ---------- things you take hold of and pull (Sky.pull in sky.js) ----------
   the open hand over them, and the closed one everywhere while you're holding on (so it stays closed as you drag
   off it). the hallway's cord and reset 4's lamp have their own pulling, in sky/attic.js: the same hands */
html body:not(.inv-holding) .pullable,
html body:not(.inv-holding) .pullable *,
html body:not(.inv-holding) .hall-cord,
html body:not(.inv-holding) .hall-cord *,
html[data-reset="4"] body:not(.lamp-down):not(.inv-holding) .hall-lamp,
html[data-reset="4"] body:not(.lamp-down):not(.inv-holding) .hall-lamp * {
    cursor: var(--cursor-grab, grab) !important;
}
html.grabbing,
html.grabbing * {
    cursor: var(--cursor-grabbing, grabbing) !important;
}
.pullable {
    touch-action: none;                    /* (a finger pulls it, rather than scrolling the page) */
}
