/* Only the forest game's page loads this stylesheet. */

/* ---- Trees ---------------------------------------------------------------
   Four kinds at three ages. A tree on the
   page shows the drawing that matches its data-stage, so growing is a change
   of shape. The foot of every drawing is at 95% of its box; the box is placed
   by that point (forest-scene.js). No filters: a tree is a few flat shapes. */
.forest-kinds{position:absolute;width:0;height:0;overflow:hidden}
.forest-patch{display:none;position:absolute;z-index:3;width:130px;height:156px;transform:translate(-50%,-95%) rotate(var(--tree-lean,0deg)) scale(var(--tree-scale,1));transform-origin:50% 95%;transition:transform 1.2s cubic-bezier(.2,.8,.2,1),opacity .6s;pointer-events:none}
.forest-patch[data-forest-seeded]{animation:forest-sprout 1.3s cubic-bezier(.2,.8,.2,1) both}
@keyframes forest-sprout{from{opacity:0;transform:translate(-50%,-95%) rotate(var(--tree-lean,0deg)) scale(.15)}}
.is-playing .forest-patch{display:block}
.forest-plant{display:block;width:100%;height:100%;overflow:visible;stroke:none;transform-origin:50% 95%;animation:tree-sway var(--sway,5.6s) ease-in-out var(--sway-start,0s) infinite alternate}
.tree-age{display:none;transform-origin:50px 114px}
.forest-plant[data-stage="1"] .tree-age[data-age="1"],.forest-plant[data-stage="2"] .tree-age[data-age="2"],.forest-plant[data-stage="3"] .tree-age[data-age="3"]{display:inline;animation:tree-grow 1.15s cubic-bezier(.2,.9,.3,1) both}
/* The whole tree leans from its foot, top farthest, the way a trunk bends. */
@keyframes tree-sway{from{transform:rotate(-1.2deg) skewX(1.1deg)}to{transform:rotate(1.2deg) skewX(-1.1deg)}}
/* A new age comes up out of the old one's height, a little past, then settles. */
@keyframes tree-grow{from{transform:scale(.74,.5);opacity:.4}55%{transform:scale(1.03,1.07);opacity:1}to{transform:none}}
.forest-root{position:absolute;left:24%;right:24%;bottom:2%;height:7px;border-radius:50%;background:#07180fb8}
/* Traced trees: each age is the same tree
   at a larger size, so growing is the tree rising to its new height and settling,
   short and eased out, from where the old age ended (--rise-from = old size / new
   size, with the patch's own scale step counted in). The sway is a plain slow lean. */
.forest-patch:is([data-art="traced"],[data-art="photo"]){transition-duration:.7s,.6s}
.forest-plant:is([data-art="traced"],[data-art="photo"]){animation-name:tree-lean}
@keyframes tree-lean{from{transform:rotate(-.7deg)}to{transform:rotate(.7deg)}}
.forest-plant:is([data-art="traced"],[data-art="photo"])[data-stage="1"] .tree-age[data-age="1"]{animation:none}
.forest-plant:is([data-art="traced"],[data-art="photo"])[data-stage="2"] .tree-age[data-age="2"]{--rise-from:.73;animation:tree-rise .7s cubic-bezier(.2,.8,.2,1) both}
.forest-plant:is([data-art="traced"],[data-art="photo"])[data-stage="3"] .tree-age[data-age="3"]{--rise-from:.8;animation:tree-rise .7s cubic-bezier(.2,.8,.2,1) both}
@keyframes tree-rise{from{transform:scale(var(--rise-from,.75))}to{transform:none}}
/* Photographic trees ('photo'): the pictures carry their own light, so no outline; the ground
   under each is a soft contact shadow thrown toward the lower right, away from the planet's
   sun (upper left). The symbols may draw beyond the box: the wide tree does. */
.forest-kinds symbol{overflow:visible}
.forest-patch[data-art="photo"] .forest-root{left:14%;right:2%;bottom:1%;height:11px;background:radial-gradient(ellipse at 42% 50%,#000000c0 0,#00000080 38%,#00000000 72%)}
/* One style (forest-look.js): the shadow is the planet's own dark, longer, thrown down
   and to the right; under each tree a thin ring of the forest's green marks the place it stands,
   brighter on the side toward the sun. The ring stays while a ship has the tree, so the place it
   belongs is seen. data-tree-ring="off" on <html> takes the rings away. */
.forest-patch[data-art="photo"] .forest-root{left:20%;right:-10%;bottom:0;height:12px;background:radial-gradient(ellipse at 34% 46%,#01060ad9 0,#01060a8c 34%,#01060a00 70%)}
.forest-patch[data-art="photo"] .forest-root::before{content:"";position:absolute;left:5%;right:39%;top:-2px;bottom:-1px;box-sizing:border-box;border-radius:50%;border:1.25px solid;border-color:#a5f093b8 #a5f0934d #a5f09338 #a5f093a6;box-shadow:0 0 7px #a5f0932e,inset 0 0 5px #a5f09324}
html[data-tree-ring=off] .forest-patch[data-art="photo"] .forest-root::before{content:none}
/* Green ground: the ground round a tree is greener, and the patch widens as
   the tree grows, so a defended forest joins up into green ground. data-green-ground="off" on <html> takes it away. */
.forest-patch[data-art="photo"]::before{content:"";position:absolute;z-index:-1;left:50%;top:95%;width:150%;height:34%;translate:-50% -50%;scale:var(--ground,1);border-radius:50%;background:radial-gradient(closest-side,#63c25e3d,#3f9a4a24 58%,#3f9a4a00);transition:scale 1.2s cubic-bezier(.2,.8,.2,1)}
.forest-patch[data-art="photo"][data-stage="2"]{--ground:1.3}.forest-patch[data-art="photo"][data-stage="3"]{--ground:1.65}
html[data-green-ground=off] .forest-patch[data-art="photo"]::before{content:none}
/* A second way to look at the trees (not the default): data-tree-look="holo" on <html>
   shows the same four photographs as projections of light, one colour, see-through, finely lined.
   The outline is still the photograph's. It uses a filter on each tree. */
html[data-tree-look=holo] .forest-plant[data-art="photo"]{filter:grayscale(1) brightness(1.75) contrast(1.15) sepia(1) hue-rotate(72deg) saturate(2.4);mix-blend-mode:screen;opacity:.92;-webkit-mask-image:repeating-linear-gradient(#000 0 2px,#0000008c 2px 3px);mask-image:repeating-linear-gradient(#000 0 2px,#0000008c 2px 3px)}
html[data-tree-look=holo] .forest-patch[data-art="photo"] .forest-root{background:none}
/* A tree being carried off is the same drawing, still. */
.cat-game-letter .forest-plant,.cat-game-letter .tree-age{animation:none!important}
.space-stage[data-game-state=paused] .forest-plant,.space-stage[data-game-state=over] .forest-plant{animation-play-state:paused}
@media(prefers-reduced-motion:reduce){.forest-patch{transition:none}.forest-patch[data-forest-seeded],.forest-plant,.forest-plant .tree-age{animation:none!important}}
/* (--tree-fit, set by forest-scene.js: on a phone the planet is smaller, and its trees with it) */
@media(max-width:699px){.forest-patch{width:calc(98px*var(--tree-fit,1));height:calc(118px*var(--tree-fit,1))}}
@media(max-width:699px) and (max-height:650px){.forest-patch{width:calc(74px*var(--tree-fit,1));height:calc(89px*var(--tree-fit,1))}}
@media(min-width:700px) and (max-height:700px){.forest-patch{width:100px;height:120px}}
@media(min-width:700px) and (max-height:520px){.forest-patch{width:66px;height:79px}}

/* Without the rendered sky the planet is a flat strip of the same picture,
   placed so the Amazon (8 S, 62 W) lies under the tree row. */
.forest-fallback{display:none;pointer-events:none;position:absolute;z-index:2;left:-5%;right:-5%;top:430px;height:260px;border-radius:50% 50% 0 0;background:linear-gradient(#1a394455,#03131bed),url('assets/earth-nasa.jpg') calc(55vw - 1311px) -944px/4000px 2000px;box-shadow:0 -1px 18px #7dcac733}
.space-stage.is-playing[data-sky=fallback] .forest-fallback{display:block}
.forest-study-return{position:fixed;right:20px;bottom:16px;z-index:35;display:inline-flex;align-items:center;min-height:44px;padding:8px 14px;background:#101b27e8;border:1px solid #8facbb55;border-radius:999px;color:#bdcbd7;font:400 12px/1.4 Inter,system-ui,sans-serif;text-decoration:none}
@media(max-width:699px){.forest-study-return{font-size:11px;right:12px;bottom:10px}}

/* ---- The page becomes the game -------------------------------------------
   Starting a run: the name, the byline and the header step back, a frame
   closes round the play field and darkens what is outside it, the cat leaves
   its place for its orbit (cat-game.js moves it), and the planet rises inside
   the frame. Close game runs it backwards. Only opacity and transforms move;
   nothing is resized while it happens. The play field is the whole window,
   so the project list is below it and out of sight. */
.space-stage.is-playing{padding-top:max(100svh,var(--forest-play-height,0px))}
.arena-frame{position:fixed;z-index:6;left:8px;top:calc(8px + var(--safe-top,0px));width:calc(100vw - 16px);height:calc(100svh - 16px - var(--safe-top,0px));box-sizing:border-box;pointer-events:none;visibility:hidden;opacity:0;transform:scale(1.07);border:1px solid #a9dfe230;border-radius:22px;box-shadow:inset 20px 0 35px -30px #72b8c250,inset -20px 0 35px -30px #72b8c250;transition:opacity .3s ease,transform .3s ease,visibility 0s .3s}
.space-stage[data-arena] .arena-frame{visibility:visible;opacity:1;transform:none;transition:opacity .45s ease,transform .75s cubic-bezier(.2,.9,.25,1.14)}
/* Four corner pieces arrive last and lock the frame. */
.arena-frame i{position:absolute;width:30px;height:30px;border:3px solid var(--ink);opacity:0;transition:opacity .2s,transform .3s}
.arena-frame i:nth-child(1){left:-2px;top:-2px;border-right:0;border-bottom:0;border-radius:22px 0 0 0;transform:translate(-14px,-14px)}
.arena-frame i:nth-child(2){right:-2px;top:-2px;border-left:0;border-bottom:0;border-radius:0 22px 0 0;transform:translate(14px,-14px)}
.arena-frame i:nth-child(3){left:-2px;bottom:-2px;border-right:0;border-top:0;border-radius:0 0 0 22px;transform:translate(-14px,14px)}
.arena-frame i:nth-child(4){right:-2px;bottom:-2px;border-left:0;border-top:0;border-radius:0 0 22px 0;transform:translate(14px,14px)}
.space-stage[data-arena] .arena-frame i{opacity:0;transform:none;transition:opacity .3s .45s,transform .45s .45s cubic-bezier(.2,.9,.25,1.3)}
.space-stage .hero-copy{transition:opacity .45s ease,scale .5s ease,translate .5s ease}
.space-stage[data-arena] .hero-copy{opacity:0;scale:.9;translate:0 -22px}
.space-stage .navigation{transition:opacity .35s ease,top .3s ease}
.space-stage[data-arena] .navigation{opacity:0}
.space-stage[data-arena] .scene-sky-control{visibility:hidden}
html.game-held .projects-section{visibility:hidden}
/* The cat is moved by cat-game.js from where it rests to its orbit and back:
   one transform about its own centre. On the far side of the orbit it goes
   under the trees and is cut where the planet covers it. */
.space-stage[data-arena] .studio-cat{transform-origin:50% 50%}
.space-stage[data-arena] .studio-cat[data-tired=true] .pupil{fill:#b86a3c}
#game-fx{position:absolute;inset:0;z-index:23;pointer-events:none}
@media(prefers-reduced-motion:reduce){.arena-frame,.arena-frame i,.space-stage .hero-copy,.space-stage .navigation{transition:none!important}}

/* ---- Readout, messages and the two buttons --------------------------------
   One band along the top of the frame. The readout is ordinary type, large.
   Close game has the right-hand column to itself; Resume (and Start
   defending, when the page has it) comes and goes in the column to its
   left, so nothing ever slides under a finger. Tab order: the button to play
   first. */
.space-stage.is-playing .play-controls{position:absolute;z-index:24;left:calc(var(--arena-x,8px) + 16px);right:auto;top:calc(var(--arena-y,8px) + 10px);bottom:auto;width:calc(var(--arena-w,100vw - 16px) - 32px);max-width:none;min-height:var(--forest-controls-height,0px);display:grid;grid-template-columns:minmax(0,1fr) auto auto;column-gap:14px;row-gap:2px;align-items:start;align-content:start}
.forest-brand{display:none}
.space-stage.is-playing .forest-brand{grid-column:1;grid-row:1;margin:0;min-height:44px;display:flex;align-items:center;font:500 18px/1.2 Inter,system-ui,sans-serif;letter-spacing:-.04em;color:var(--ink)}
.space-stage.is-playing .forest-hud{grid-column:1/-1;grid-row:2;min-height:30px}
.space-stage.is-playing #forest-ready,.space-stage.is-playing #forest-resume{grid-column:2;grid-row:1;margin:0}
.space-stage.is-playing #play-stop{grid-column:3;grid-row:1;margin:0;font-size:14px}
.space-stage.is-playing .play-status{grid-column:1/-1;grid-row:3;max-width:46ch;font-size:14px;line-height:1.5}
.space-stage.is-playing .forest-clue{grid-column:1/-1;grid-row:4}
.forest-hud{margin:0;min-height:44px;display:flex;align-items:center;font:600 clamp(20px,2.3vw,28px)/1.2 Inter,system-ui,sans-serif;letter-spacing:-.015em;color:var(--ink);text-shadow:0 2px 8px #000d}
.forest-clue{margin:4px 0 0;max-width:46ch;font:italic 400 14px/1.5 Inter,system-ui,sans-serif;color:#c3d3bf;text-shadow:0 2px 6px #000;text-wrap:pretty}
@media(min-width:700px){.space-stage.is-playing .play-status,.space-stage.is-playing .forest-clue{max-width:72ch}}
/* A short window: the messages use the frame's width and smaller type, so the band stays shallow. */
@media(max-height:520px){.space-stage.is-playing .play-status,.space-stage.is-playing .forest-clue{max-width:none;font-size:13px;line-height:1.4}.forest-clue{margin-top:2px}.forest-hud{font-size:20px}}
.forest-ready{display:inline-flex;align-items:center;min-height:44px;padding:8px 16px;border:1px solid #b6d1b77a;border-radius:999px;background:#0b141ccc;color:var(--ink);font:500 14px/1.4 Inter,system-ui,sans-serif}
.forest-ready:hover{border-color:var(--teal);color:var(--ink);background:#1a2b2fcc}
.space-stage.is-playing:focus-visible .play-controls{outline:none}
/* The last run's result stays with the cat, yielding to its play invitation. */
.studio-cat .forest-last{position:absolute;top:82%;left:50%;transform:translateX(-50%);width:max-content;max-width:90vw;margin:0;font:400 14px/1.5 Inter,system-ui,sans-serif;letter-spacing:0;color:var(--dim);pointer-events:none;transition:opacity .2s}
.studio-cat[data-cue-ready=true]:is(:hover,:focus-visible) .forest-last,.is-docking .forest-last{opacity:0}

.forest-results{position:fixed;z-index:25;left:50%;top:var(--forest-results-centre,50%);transform:translate(-50%,-50%);width:min(330px,calc(100vw - 48px));max-height:calc(100svh - 150px);overflow:auto;overscroll-behavior:contain;padding:22px 24px 18px;border:1px solid #9bcb9452;border-radius:16px;background:#070e14eb;box-shadow:0 12px 40px #00000099;text-align:center;color:var(--ink)}
.forest-results h2{margin:0 0 10px;font:600 20px/1.3 Inter,system-ui,sans-serif;letter-spacing:-.01em}
.forest-results p{margin:0;font:400 14px/1.8 Inter,system-ui,sans-serif;color:#c4cdd8}
.forest-results button{display:inline-flex;align-items:center;justify-content:center;min-height:44px;margin-top:12px;padding:8px 20px;border:1px solid #b6d1b77a;border-radius:999px;background:#91b98416;color:var(--ink);font:500 14px/1.4 Inter,system-ui,sans-serif}
.forest-results button:hover{border-color:var(--teal);background:#91b98429}
@media(max-height:420px){.forest-results{max-height:calc(100svh - 76px);top:calc(50% + 30px);padding:12px 20px 10px}.forest-results p{line-height:1.5}.forest-results button{margin-top:6px}}

/* Staying in the game. From the first frame to Close game the page outside
   the play field is inert (cat-game.js); here it also stops answering a
   finger: no scroll, zoom, pull-to-refresh, text selection or long-press
   menu. A paused game holds the page as well, so Resume and Close game stay
   in view (HOLD_PAGE_WHEN_PAUSED in cat-game.js gives scrolling back). */
html.game-held{overscroll-behavior:none}
html.game-held .space-stage.is-playing{touch-action:none}
html.game-paused-scrolls .space-stage.is-playing[data-game-state=paused]{touch-action:auto}
html.game-held .space-stage.is-playing{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}
html.game-held .space-stage.is-playing .scene-controls{visibility:hidden}
.space-stage.is-playing[data-game-state=paused] #game-canvas{opacity:.55;touch-action:auto}
.space-stage.is-playing .scene-shade{background:none}
