/* Harper arrival: one full-screen photographed space. The ten existing title
   buttons pull back around it, then become the same rotary nodes on entry. */
html:not(.has-prints) .sky{background:#f8f7f2}
html:not(.has-prints) .sky::after{inset:0;z-index:0;background:url('./assets/harper-oasis-wide.webp') center/cover;mix-blend-mode:normal;opacity:1;transform:scale(1.015);transform-origin:50% 50%;filter:saturate(.96);transition:transform 1.2s cubic-bezier(.18,.78,.2,1),opacity .7s ease;pointer-events:none}
html.material-ready:not(.has-prints) .sky::after{opacity:0}
html:not(.has-prints) .sky::before{opacity:.08}
html:not(.has-prints) .sky .pool,html:not(.has-prints) .sky .floor{opacity:0}
html:not(.has-prints) .sky .world{opacity:.02}
.sky .arrival-materials{position:absolute;inset:0;z-index:1;overflow:hidden;opacity:0;transition:transform 1.28s cubic-bezier(.17,.76,.18,1),opacity .95s ease,filter 1.08s ease;pointer-events:none}
html.material-ready:not(.has-prints) .sky .arrival-materials{opacity:1}
.sky .arrival-material{display:block;position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;opacity:0;transform:scale(1.015);transition:transform 1.25s cubic-bezier(.18,.78,.2,1);will-change:opacity}
.sky .arrival-material.is-active{opacity:1}
.sky .material-morph{position:absolute;inset:0;z-index:1;display:block;width:100%;height:100%;opacity:0;pointer-events:none;transition:opacity .24s ease}
.sky .material-morph.is-ready{opacity:1}
.sky .arrival-materials::after{content:"";position:absolute;inset:0;z-index:2;background:#f7f9fc58;opacity:0;pointer-events:none;transition:opacity .95s ease,background .95s ease}
.sky .material-light{position:absolute;inset:0;z-index:2;display:block;width:100%;height:100%;pointer-events:none;opacity:0;mix-blend-mode:screen;transform:translate3d(var(--space-x,0px),var(--scene-y,0px),0) scale(var(--scene-zoom,1));transition:opacity .65s ease}
html.material-ready:not(.has-prints) .sky .material-light[data-light=ready]{opacity:.8}
html[data-theme=dark].material-ready:not(.has-prints) .sky .material-light[data-light=ready]{opacity:.5}
html.has-prints .sky .material-light{opacity:0}
html:not(.has-prints):has(.scene-upload:hover) .sky .arrival-material,html.dragging:not(.has-prints) .sky .arrival-material{transform:scale(1.045)}
html:not(.has-prints):has(.scene-upload:hover) .sky::after,html.dragging:not(.has-prints) .sky::after{transform:scale(1.045)}
html.has-prints .sky .arrival-materials{opacity:0;transform:scale(1.48);filter:blur(5px);transition:opacity .8s ease,transform 1.05s cubic-bezier(.18,.78,.2,1),filter .8s ease}
html.has-prints .sky::after{opacity:0;transform:scale(1.48);filter:blur(5px)}
html[data-theme=dark]:not(.has-prints) .sky{background:#17212e}
html[data-theme=dark]:not(.has-prints) .sky .arrival-materials::after{background:#10213a91;opacity:1}
html[data-theme=dark]:not(.has-prints) .sky::after{filter:brightness(.55) saturate(.8)}

/* The photographed plate resolves first, then the collage and mode objects
   enter over it. This class is set in the head, before the first paint. */
html.booting:not(.has-prints) .sky .arrival-materials{opacity:0;filter:blur(25px) saturate(.72)}
html.booting:not(.has-prints) .sky::after{filter:blur(18px) saturate(.82);transform:scale(1.07)}
html.booting.material-ready:not(.has-prints) .sky::after{opacity:1;filter:blur(18px) saturate(.82)}
html.booting[data-theme=dark]:not(.has-prints) .sky::after{filter:blur(18px) brightness(.55) saturate(.8)}
html.booting:not(.has-prints) .arrive{opacity:0!important;filter:blur(14px)!important;animation:none!important}
html.booting:not(.has-prints) .wheel .tool-title{opacity:0!important;filter:blur(9px)!important}
html.booting:not(.has-prints) .sample-fan,html.booting:not(.has-prints) .how{opacity:0!important}

/* The photographed concentric contours are the shared spatial map. Synthetic
   orbit rings would compete with each tool's physical material. */
.arrival-space{display:none}

/* The entire photograph is the upload surface. Text and mode objects sit above
   it, preserving the familiar opening composition and simple click path. */
html .scene-upload{all:unset;box-sizing:border-box;position:absolute;inset:57px 0 0;z-index:2;display:block;cursor:pointer;pointer-events:none;opacity:1;transition:opacity .5s ease;-webkit-tap-highlight-color:transparent}
html.has-prints .scene-upload,html:not(.has-prints):has(.print.leaving) .scene-upload{opacity:0;pointer-events:none}
html .scene-upload:focus-visible{outline:none}
.upload-canvas{position:absolute;left:50%;top:63%;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box;width:202px;height:143px;color:#1e3960;pointer-events:auto;transform:translate(-50%,-50%);transition:transform .4s cubic-bezier(.2,.8,.2,1),color .4s ease;white-space:nowrap}
.upload-frame{position:absolute;inset:0;border:1.5px solid #7c8aa3a6;border-radius:17px;background:#ffffffe0;box-shadow:0 1px 0 #fff inset,0 8px 20px #35496429,0 20px 46px #35496418;backdrop-filter:blur(12px);clip-path:inset(48% 49% round 10px);animation:upload-outline 1.05s .72s cubic-bezier(.17,.82,.21,1) forwards;transition:border-color .35s,box-shadow .35s,background .35s}
.upload-plus{position:relative;display:block;width:34px;height:34px;margin:-7px 0 11px;animation:plus-arrive .75s .15s both}
.upload-plus i{position:absolute;left:50%;top:50%;display:block;border-radius:4px;background:#344fc3;transform:translate(-50%,-50%);box-shadow:0 1px 0 #fff9}
.upload-plus i:first-child{width:30px;height:3px}.upload-plus i:last-child{width:3px;height:30px}
.upload-copy{position:relative;font:700 15px/1.1 var(--font);letter-spacing:-.025em;opacity:0;animation:upload-label .55s 1.4s forwards}
.upload-subcopy{position:relative;margin-top:5px;color:#5b6b83;font:500 10px/1.2 var(--font);opacity:0;animation:upload-label .55s 1.52s forwards}
html .scene-upload:hover .upload-canvas,html .scene-upload:focus-visible .upload-canvas{transform:translate(-50%,-54%) scale(1.06)}
html .scene-upload:hover .upload-frame,html .scene-upload:focus-visible .upload-frame{border-color:#4a60c7;background:#fffffff5;box-shadow:0 0 0 5px #536ae81e,0 16px 33px #253a6950}
html .scene-upload:hover .upload-plus,html .scene-upload:focus-visible .upload-plus{animation:none;transform:rotate(90deg);transition:transform .45s cubic-bezier(.2,.8,.2,1)}
html.dragging:not(.has-prints) .scene-upload{box-shadow:inset 0 0 0 10px rgb(var(--accent-rgb,68 89 213)/.35)}
html.dragging:not(.has-prints) .upload-canvas{transform:translate(-50%,-50%) scale(1.13)}
html.dragging:not(.has-prints) .upload-frame{border-color:var(--accent,#5164d3);box-shadow:0 0 0 9px rgb(var(--accent-rgb,68 89 213)/.22),0 20px 40px #253a6950}
html.dragging:not(.has-prints) .upload-copy{font-size:0}
html.dragging:not(.has-prints) .upload-copy::after{content:'Release to open';font-size:15px}
html[data-theme=dark] .upload-frame{background:#e7edf5e8;border-color:#a4b4d1}
@keyframes upload-outline{from{clip-path:inset(48% 49% round 10px);opacity:.4;transform:scale(.35)}to{clip-path:inset(0 0 0 0 round 17px);opacity:1;transform:scale(1)}}
@keyframes plus-arrive{from{opacity:0;transform:scale(.3) rotate(-90deg)}to{opacity:1;transform:scale(1) rotate(0)}}
@keyframes upload-label{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:translateY(0)}}

html .arrive{top:39%;width:min(82vw,790px);gap:0;padding:0;z-index:3;pointer-events:none;transform:translate(-50%,-50%) scale(1);filter:none;transition:opacity .5s ease,transform 1.05s cubic-bezier(.18,.78,.2,1),filter .6s}
html:not(.has-prints) .arrive{translate:var(--hero-x,0px) var(--hero-y,0px);animation:hero-reveal 1.1s cubic-bezier(.18,.78,.2,1) both}
html.has-prints .arrive{opacity:0;transform:translate(-50%,-50%) scale(1.38);filter:blur(7px)}
html:not(.has-prints):has(.print.leaving) .arrive{animation:none;opacity:0}
html .arrival-kicker{margin:0 0 2px;color:#3a4e69;font:700 10px/1.3 var(--mono);letter-spacing:.24em;text-shadow:0 1px 2px #fff}
html .wordmark{position:relative;display:block;width:min(50vw,620px);aspect-ratio:1950/807;max-width:none;margin:0;line-height:0;filter:drop-shadow(0 9px 8px #2f405c2a)}
html .wordmark .word-scrap{position:absolute;inset:0;display:block;clip-path:inset(0 var(--crop-right) 0 var(--crop-left));transform-origin:var(--origin) 50%;will-change:transform}
html .wordmark .word-scrap img{display:block;width:100%;height:100%;object-fit:contain;border:0;border-radius:0;box-shadow:none}
html .arrival-line{margin:-11px 0 0;color:#273957;font:italic 20px/1.25 Georgia,serif;letter-spacing:-.025em;text-shadow:0 1px 3px #fff}
html .arrive-sub{display:flex;align-items:center;gap:7px;margin:24px 0 0;padding:6px 12px;border-radius:100px;background:#fffc;color:#405574;font:600 11px/1.3 var(--font);box-shadow:0 1px 4px #273b5720}
html .arrive-sub b{color:#263c64;font-weight:650}
.mode-pip{width:7px;height:7px;flex:none;border-radius:50%;background:var(--accent,#6170dc);box-shadow:0 0 0 3px rgb(var(--accent-rgb,97 112 220)/.14)}
.arrive-divider{color:#8798af;margin:0 2px}
html[data-theme=dark] .arrival-kicker,html[data-theme=dark] .arrival-line{color:#f2f5fb;text-shadow:0 2px 7px #08101e}
html[data-theme=dark] .arrive-sub{background:#1d2a3fcc;color:#edf2ff}
html[data-theme=dark] .arrive-sub b{color:#fff}
@keyframes hero-reveal{from{opacity:0;transform:translate(-50%,-50%) scale(.8);filter:blur(7px)}to{opacity:1;transform:translate(-50%,-50%) scale(1);filter:blur(0)}}

/* Same-node mode promotion: overview positions are written onto the same
   ten .tool-title elements used by the close-up rotary. */
html:not(.has-prints) .wheel{height:100svh;opacity:1;pointer-events:none;overflow:visible;-webkit-mask-image:none;mask-image:none}
html:not(.has-prints) .wheel .tool-title{pointer-events:auto;transform-origin:50% 50%;filter:drop-shadow(0 7px 7px #293c5e38);transition:filter .35s ease}
html:not(.has-prints) .wheel .tool-title:hover,html:not(.has-prints) .wheel .tool-title:focus-visible{filter:drop-shadow(0 16px 14px #25365278) brightness(1.06)}
html:not(.has-prints) .wheel .tool-title[aria-selected=true]{filter:drop-shadow(0 12px 13px rgb(var(--accent-rgb)/.48))}
html:not(.has-prints) .wheel .tool-title[aria-selected=true] .brand-art .logo-img{animation-play-state:running!important}
html.idle:not(.has-prints) .wheel .tool-title[aria-selected=true] .brand-art .logo-img,html.logo-motion-paused:not(.has-prints) .wheel .tool-title[aria-selected=true] .brand-art .logo-img{animation-play-state:paused!important}
.orbit-label{display:none}
html.camera-travel .wheel{overflow:visible!important;-webkit-mask-image:none!important;mask-image:none!important;opacity:1!important}
html.camera-travel .wheel .tool-title{visibility:visible!important;pointer-events:none!important}
html:not(.has-prints) .studio-header .notch-mark{font:400 21px/1 Georgia,serif;letter-spacing:-.05em;transform:none}
html:not(.has-prints) .how{right:50%;bottom:18px;transform:translateX(50%);font:600 11px/1 var(--font);color:#293e63;text-shadow:0 1px 2px #fff}
html:not(.has-prints) .how svg{color:inherit}

@media(max-width:1100px){
 html .wordmark{width:min(55vw,560px)}
 html .arrive{top:40%}
}
@media(max-width:719px){
 html .scene-upload{inset:76px 0 0}
 html .arrive{top:39%;width:100vw}
 html .arrival-kicker{font-size:7px;letter-spacing:.13em}
 html .wordmark{width:min(75vw,350px)}
 html .arrival-line{font-size:15px;margin:-4px 0 0}
 html .arrive-sub{margin-top:11px;font-size:9px;padding:5px 8px;gap:4px}
 .upload-canvas{top:62%;width:170px;height:125px}
 .upload-plus{margin:-3px 0 8px;transform:scale(.9)}
 .upload-copy{font-size:13px}
 .upload-subcopy{font-size:9px}
 html:not(.has-prints) .wheel .orbit-label{position:absolute;left:50%;bottom:-18px;display:block;width:max-content;max-width:98%;padding:5px 10px;border:1px solid #dce3ee;border-radius:20px;background:#ffffffed;box-shadow:0 3px 7px #1f315321;color:#304262;font:700 23px/1 var(--font);letter-spacing:-.025em;text-align:center;transform:translateX(-50%)}
 html:not(.has-prints)[data-theme=dark] .wheel .orbit-label{background:#202b40ed;color:#f0f4fb;border-color:#6e819e}
 html:not(.has-prints) .how{bottom:9px;font-size:10px}
}
@media(max-width:400px){html .arrive-sub{font-size:8px}}
@media(max-height:720px) and (min-width:720px){html .wordmark{width:min(42vw,470px)}html .arrive{top:36%}.upload-canvas{top:63%}}
@media(prefers-reduced-motion:reduce){html .sky::after,html .arrive,.arrival-materials,.arrival-material,.material-light,.upload-canvas,.upload-frame,.upload-plus,.upload-copy,.upload-subcopy,.wheel .tool-title{transition:none!important;animation:none!important}html.has-prints .arrive{filter:none}.upload-frame{clip-path:none}.upload-copy,.upload-subcopy{opacity:1}}

/* Scroll brings the camera toward the carved surface. The same photographic
   plate stays in place under every tool material; scraps lift at their own
   depths while the guide enters below. All values return to zero on scroll-up. */
html:not(.has-prints) .sky .arrival-materials{transform:translate3d(var(--space-x,0px),var(--scene-y,0px),0) scale(var(--scene-zoom,1))}
html:not(.has-prints) .sky::after{transform:translate3d(var(--space-x,0px),var(--scene-y,0px),0) scale(var(--scene-zoom,1))}
html:not(.has-prints) .wordmark{translate:0 var(--wordmark-y,0px)}
html:not(.has-prints) .upload-canvas{translate:0 var(--canvas-y,0px);scale:var(--canvas-scale,1)}
@media(prefers-reduced-motion:reduce){html:not(.has-prints) .sky .arrival-materials,html:not(.has-prints) .sky::after,html:not(.has-prints) .sky .material-light{transform:none}html:not(.has-prints) .wordmark,html:not(.has-prints) .upload-canvas{translate:none;scale:1}}
