/* C09 stage: the R36 3D hotel is the hero (Owner 2026-09-24T08:08:20Z: “突出我的3d模型和3d订房系统”).
   One sticky full-screen stage: cinematic 3D under the headline → scroll to “choose your room” (picker slides in,
   camera flies to the room) → continue to booking. The real pool photo is the poster until 3D is ready. */
.stage{position:relative;height:230vh;background:#11271a}
.stage-sticky{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden}
/* First paint is already the photo: a 48px blurred copy of hero-pool.webp (358 bytes) sits under the real image,
   so slow connections see the pool at once instead of an empty band. */
.stage-media{background:#11271a url("data:image/webp;base64,UklGRl4BAABXRUJQVlA4IFIBAAAQCACdASowABsAPt1krVAopSQipWsxEBuJagCsMscIgIJHAjHR56h4EdEXzC5X2j0fLp6FJVAvHrpzfgOzyeD5+3AHVeHugkwgAP7yBXF36PhBr4GChhHZDLiQHYUj2XAJ673iIDcOAKuzAFzeVxc/c8sstV1+WR1Hf6CoMGFgMeI/rSdp50dkdIY7rIvqZl0B89j4pKsaeLk8q9FyhdCLQvWU5FERYhRTKce9sSJWZLovdGOdjqVzf5Bi1rYuugY01Q2YcjATz3xynqZp//OQhHf/5xcVcEOtn2aBCpHYD0DEaUMTxX+b1vtxxQ1JpOx7KFZ0Eu86qMCHWg486gu3YEb5yKLEkDvg7tVSAQnJFn4gKpJVar3HOi294i8N3zrLI/A0Wi5jxLJ9kMFhuZoT+1uolUUSRa0KwPy/zjMYK3zzY1uxFHFeQsi1Sg1re4AAAA==") center 56%/cover no-repeat}
.stage-media,.stage .viewer-area,.stage #viewer-shell,.stage #viewer{position:absolute;inset:0;width:100%;height:100%}
.stage .viewer-area{margin:0;border:0;background:none}
.stage #viewer-poster,.stage .viewer-caption,.stage #viewer-status{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.stage #viewer iframe{pointer-events:none}
/* Photo first: the 3D frame stays invisible while it loads and warms up, then fades in over the photo. */
.stage #viewer-shell{background:none;border:0;opacity:0;transition:opacity 1.6s ease}
.stage.is-live #viewer-shell{opacity:1}
.stage.is-interactive #viewer iframe{pointer-events:auto}
.stage-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transform:scale(1.04);transition:opacity 1.4s ease,transform 12s ease-out}
.stage.is-loading .stage-poster{transform:scale(1.1)}
.stage.is-live .stage-poster{opacity:0;pointer-events:none}
.stage-shade{position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,#0c2014d9 0%,#0c201466 38%,#0c201400 70%),linear-gradient(0deg,#0c2014a6 0%,#0c201400 45%);transition:opacity .8s}
.stage.is-pick .stage-shade,.stage.is-interactive .stage-shade{opacity:.25}
.stage-copy{position:absolute;left:7%;bottom:13vh;max-width:680px;color:#fff;z-index:2;transition:opacity .7s ease,transform .7s ease}
.stage-copy h1{color:#fff;text-shadow:0 2px 30px #0c201466}
.stage.is-pick .stage-copy,.stage.is-interactive .stage-copy{opacity:0;transform:translateY(-24px);pointer-events:none}
.stage-loading{margin-top:18px;font-size:13px;letter-spacing:.08em;color:#ffffffcc;min-height:1.4em}
.stage-loading::before{content:'';display:inline-block;width:var(--stage-progress,0%);max-width:160px;height:2px;margin-right:10px;vertical-align:middle;background:#fff;transition:width .3s}
.stage.is-live .stage-loading{opacity:0;transition:opacity .6s}
/* Room picker while the 3D still loads: the same thin progress line, on the panel's top edge (C00 10-01: light hint, no new block). */
.stage.is-loading.is-pick .stage-picker::before{content:'';position:absolute;left:0;top:0;height:2px;width:var(--stage-progress,0%);background:#2E5A2C;transition:width .3s;pointer-events:none}
.stage .stage-picker{position:absolute;z-index:3;right:4%;top:50%;width:min(390px,92vw);max-height:82vh;overflow:auto;margin:0;padding:26px 26px 22px;
 background:#fcfbf6f0;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-radius:14px;box-shadow:0 24px 60px #0c201440;
 transform:translate(calc(100% + 8vw),-50%);transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.stage.is-pick .stage-picker{transform:translate(0,-50%)}
.stage.is-interactive .stage-picker{transform:translate(calc(100% + 8vw),-50%)}
.stage-picker h2{font-size:clamp(28px,2.6vw,38px);margin:.2em 0 .6em}
.stage-price{font-weight:600;font-size:15px;margin:.8em 0 0;color:var(--ink,#18261b)}
.stage-done{position:absolute;z-index:4;top:20px;right:20px}
.stage-done[hidden]{display:none}
.stage-scroll-hint{position:absolute;left:50%;bottom:22px;width:1px;height:44px;background:linear-gradient(#fff0,#fffc);z-index:2;animation:stage-hint 2.4s ease-in-out infinite}
.stage.is-pick .stage-scroll-hint,.stage.is-interactive .stage-scroll-hint{display:none}
@keyframes stage-hint{0%{transform:translateY(-10px);opacity:0}50%{opacity:1}100%{transform:translateY(10px);opacity:0}}
.stage-step{position:absolute;left:0;right:0;top:115vh;height:100vh;pointer-events:none}
@media(max-width:760px){
 .stage{height:220vh}
 .stage-copy{left:22px;right:22px;bottom:12vh}
 .stage .stage-picker{left:0;right:0;top:auto;bottom:0;width:auto;max-height:54vh;border-radius:16px 16px 0 0;padding:18px 18px 20px;transform:translateY(105%)}
 .stage.is-pick .stage-picker{transform:none}
 .stage.is-interactive .stage-picker{transform:translateY(105%)}
 .stage-picker .micro,.stage-picker #selected-image{display:none}
 .stage-done{top:14px;right:14px}
}
@media(prefers-reduced-motion:reduce){.stage #viewer-shell,.stage-poster,.stage-copy,.stage .stage-picker,.stage-shade{transition:none}.stage-scroll-hint{animation:none}.stage.is-loading .stage-poster{transform:none}}

.stage-copy .eyebrow{color:#ffffffd9;text-shadow:0 1px 12px #0c201499}
.stage-picker #selected-image{display:none}

/* “← All rooms”: quiet text button at the top of the room panel. */
.stage-all{display:inline-block;margin:0 0 12px;padding:4px 0;border:0;background:none;color:var(--muted,#4b5b48);font:500 13px/1.4 var(--sans,system-ui);cursor:pointer}
.stage-all:hover,.stage-all:focus-visible{color:var(--ink,#18261b);text-decoration:underline;text-underline-offset:3px}

/* “Choose your room”: drag to turn the room with a mouse, and a clear button into the full 3D (Owner 13:27Z). */
/* Only explicit interactive mode receives pointer input, including on desktop. */
.stage-3d{position:absolute;z-index:4;left:4%;bottom:6vh;display:inline-flex;align-items:center;gap:10px;height:48px;padding:0 20px 0 16px;
 border:1px solid #ffffff66;border-radius:24px;background:#18261bb3;color:#fff;font:600 15px/1 var(--sans,system-ui);letter-spacing:.01em;
 backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);box-shadow:0 10px 30px #0c201440;cursor:pointer;
 opacity:0;transform:translateY(10px);pointer-events:none;transition:opacity .35s ease,transform .35s cubic-bezier(.2,.8,.2,1),background .2s ease}
.stage.is-pick.is-live:not(.is-interactive) .stage-3d,.stage.is-pick.is-photo:not(.is-interactive) .stage-3d{opacity:1;transform:none;pointer-events:auto}
.stage.is-interactive .stage-3d{opacity:0;pointer-events:none}
.stage-3d:hover{background:#2e5a2ce6;transform:translateY(-1px)}
.stage-3d:active{transform:scale(.97)}
.stage-3d:focus-visible{outline:3px solid #2c958b;outline-offset:3px}
@media(max-width:760px){.stage-3d{left:16px;top:84px;bottom:auto;height:44px;font-size:14px}}
@media(prefers-reduced-motion:reduce){.stage-3d{transition:none}}

/* Phones, portrait and landscape (Owner: “手机版的3d模型最好可以横竖都能显示，按钮不挡屏幕”): full 3D takes the whole screen,
   above the site header, the chat button and the booking bar; only the viewer's own controls and a compact Done stay. */
@media(max-width:760px),(max-height:500px){
 .stage.is-interactive .stage-sticky{position:fixed;inset:0;z-index:90;height:100%;height:100dvh}
 html.oh-3d-full,html.oh-3d-full body{overflow:hidden}
 html.oh-3d-full .oh-chat-fab,html.oh-3d-full .mobile-book{display:none!important}
 .stage-done{top:calc(8px + env(safe-area-inset-top,0px));right:calc(8px + env(safe-area-inset-right,0px));height:40px;min-height:40px;padding:0 16px;font-size:14px;line-height:1}
}
/* Landscape phones, “choose your room”: a compact room panel, so the model and the 3D button stay in view. */
@media(min-width:761px) and (max-height:500px){
 .stage .stage-picker{width:min(330px,40vw);top:10px;max-height:calc(100% - 86px);padding:12px 16px 14px;right:12px;transform:translate(calc(100% + 8vw),0)}
 .stage.is-pick .stage-picker{transform:none}
 .stage.is-interactive .stage-picker{transform:translate(calc(100% + 8vw),0)}
 .stage-picker .eyebrow,.stage-picker .stage-all{display:none}
 .stage-picker h2{font-size:22px;margin:0 0 .4em}
 .stage-picker .type-tabs button{padding-top:6px;padding-bottom:6px}
 .stage-3d{left:16px;bottom:14px;height:42px;font-size:14px}
 .stage-copy{bottom:16vh}
 html:has(.stage.is-pick) .oh-chat-fab .oh-chat-fab-label{display:none}
}
/* Full 3D on every screen (Owner 09-25: 左侧面板没显示全): the stage covers the whole window above the site header, as on
   phones. Before, on desktop it began under the 90px header and stayed 100vh tall, so its bottom 90px, with the end of the
   viewer's room panel, sat below the screen (scrollIntoView could not help: scroll-padding-top kept the page at the top). */
.stage.is-interactive .stage-sticky{position:fixed;inset:0;z-index:90;height:100%;height:100dvh}
html.oh-3d-full,html.oh-3d-full body{overflow:hidden}
html.oh-3d-full .oh-chat,html.oh-3d-full .mobile-book{display:none!important}
/* The stage clips instead of hiding overflow: with overflow:hidden, focusing something inside it (the room panel parked off
   screen) scrolled the stage box itself, shifting the 3D up or left by 15-80px so the viewer's panel and buttons were cut. */
.stage-sticky{overflow:clip}
/* Persistent escape route. Both entry and exit occupy the same clear, touch-sized slot. */
.stage-navigation{position:absolute;z-index:8;left:4%;top:20px;display:flex;align-items:center;gap:6px;padding:6px;border:1px solid #ffffff70;border-radius:30px;background:#18261bf2;color:#fff;box-shadow:0 8px 26px #0c201440;max-width:calc(100% - 8%);touch-action:pan-y}
.stage-navigation a,.stage-navigation .stage-3d,.stage-navigation .stage-done{position:static;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:46px;height:auto;padding:12px 16px;margin:0;border:0;border-radius:24px;background:transparent;color:#fff;font:600 15px/1.25 var(--sans,system-ui);opacity:1;transform:none;pointer-events:auto;box-shadow:none;white-space:nowrap}
.stage-navigation .stage-3d,.stage-navigation .stage-done{background:#fcfbf6;color:#18261b}
.stage-navigation [hidden]{display:none!important}
.stage-navigation a:hover,.stage-navigation a:focus-visible{background:#ffffff24}
.stage-navigation :focus-visible{outline:3px solid #60d5c5;outline-offset:2px}
.stage-scroll-hint{display:none}
.stage.is-interactive .stage-media{bottom:82px;height:auto}
.stage.is-interactive .stage-navigation{top:auto;bottom:12px}
/* Landscape phones and other short screens (Owner row 62: the band under the 3D still took a fifth of the height): the 3D reaches the
   bottom edge and the three buttons become a small capsule floating at the lower right, clear of the viewer's room sheet at the lower left. */
@media(min-width:761px) and (max-height:500px){
 .stage.is-interactive .stage-media{bottom:0}
 .stage.is-interactive .stage-navigation{left:auto;right:calc(12px + env(safe-area-inset-right,0px));bottom:calc(10px + env(safe-area-inset-bottom,0px));padding:4px;gap:2px;max-width:calc(100% - 24px)}
 .stage.is-interactive .stage-navigation a,.stage.is-interactive .stage-navigation .stage-3d,.stage.is-interactive .stage-navigation .stage-done{min-height:40px;padding:8px 12px;font-size:14px}
}
/* The phone controls have their own band, outside the model and room sheet. */
@media(max-width:760px){
 .stage{--stage-dock:calc(76px + env(safe-area-inset-bottom,0px))}
 .stage:not(.is-interactive) .stage-sticky{top:var(--stage-header-visible,72px);height:calc(100svh - var(--stage-header-visible,72px))}
 .stage .stage-media,.stage.is-interactive .stage-media{top:0;bottom:var(--stage-dock);height:auto}
 .stage #viewer-shell{min-height:0}
 .stage-navigation,.stage.is-pick:not(.is-interactive) .stage-navigation,.stage.is-interactive .stage-navigation{left:0;right:0;top:auto;bottom:0;max-width:none;height:var(--stage-dock);box-sizing:border-box;justify-content:center;gap:2px;padding:10px 10px calc(10px + env(safe-area-inset-bottom,0px));border:0;border-radius:0;background:#11271a;box-shadow:none}
 .stage-navigation a,.stage-navigation .stage-3d,.stage-navigation .stage-done{min-height:44px;min-width:0;padding:10px 10px;font-size:14px;white-space:normal;text-align:center}
 .stage-copy{top:auto;bottom:calc(var(--stage-dock) + clamp(24px,6svh,52px))}
 .stage .stage-picker{bottom:var(--stage-dock);max-height:calc(100% - var(--stage-dock) - 80px)}
 html.oh-stage-rail-visible .oh-chat:not(.is-open){bottom:calc(88px + env(safe-area-inset-bottom,0px))}
 html.oh-stage-rail-visible .oh-chat:not(.is-open) .oh-chat-fab{min-height:44px;padding:8px 12px}
}
@media(max-width:760px) and (max-height:650px){
 .stage-copy{bottom:calc(var(--stage-dock) + 16px)}
 .stage-copy h1{font-size:clamp(2.35rem,10vw,3.3rem)}
 .stage-copy .hero-buttons{flex-direction:row;flex-wrap:wrap;gap:12px;margin-top:16px}
 .stage-copy .stage-loading{margin-top:6px}
}

/* Portrait phones (Owner 09-25 「…被转化特效卡住…不好往下拉屏幕」): the room-picker sheet held more than its 54vh, so it became a
   scroller inside the page and caught the first swipes. Compact like the landscape phone sheet (no eyebrows, tighter gaps)
   and a little taller, so it fits and every swipe scrolls the page. */
@media(max-width:760px) and (min-height:501px){
 .stage .stage-picker{max-height:min(60vh,calc(100% - var(--stage-dock) - 80px))}
 .stage-picker .eyebrow{display:none}
 .stage-picker h2{margin:0 0 8px}
 .stage-picker .type-tabs,.stage-picker .room-chips{margin-bottom:12px}
 .stage-picker .selected-summary{margin-top:10px}
 .stage-picker #room-note{margin:8px 0}
}
/* Desktop full 3D (Owner 346, 09-30): the hero's shade dimmed the viewer's left panel to grey (#fffdf7 read as #cdcfc9). The hero copy is
   hidden in full 3D, so the shade goes; the first screen and phones keep it. (C09) */
@media(min-width:761px) and (min-height:501px){.stage.is-interactive .stage-shade{opacity:0}}

/* HOTEL-WEB-PHOTOS-3D-R1: desktop entry/exit are one fixed slot. Swapping the hidden sibling cannot move Book or Continue. */
@media(min-width:761px) and (min-height:501px){
 .stage-navigation{--stage-3d-slot:176px}
 .stage-navigation .stage-3d,.stage-navigation .stage-done{box-sizing:border-box;inline-size:var(--stage-3d-slot);flex:0 0 var(--stage-3d-slot)}
 .stage-navigation .stage-3d svg,.stage-navigation .stage-done svg{width:18px;height:18px;flex:0 0 18px}
}

/* HOTEL-WEB-3D-PILL-R1 (Owner 10-01: before 3D the bar sat at the top left, in 3D at the bottom left): on desktop the bar is ONE box in ONE place
   in both states, bottom left of the stage, like the phone bottom bar. The same first button swaps 操作 3D ⇄ 退出 3D in that box, so the mouse can
   enter and leave 3D without moving. It is a sticky flex item at the end of the stage column, not absolute: on the first screen the header still
   pushes the stage 90px down, so an absolute bar at the stage's bottom edge would sit below the fold; sticky keeps it 12px above the window's
   bottom edge at every scroll position, exactly where the fixed full-screen 3D stage puts it. Phones and short landscape screens keep their own rules above. */
@media(min-width:761px) and (min-height:501px){
 .stage-sticky{display:flex;flex-direction:column;justify-content:flex-end}
 .stage-navigation,.stage.is-interactive .stage-navigation{position:sticky;left:auto;top:auto;bottom:12px;margin:0 auto 12px 4%;align-self:flex-start;flex:none}
 /* The Exit button is a .pill (controls.css lifts it 1px on hover and shrinks it on press); the Explore button is not. With the mouse resting on the same spot
    the two would differ by a pixel, so neither moves. */
 .stage-navigation :is(.stage-3d,.stage-done):is(:hover,:active){transform:none;box-shadow:none}
 /* Short windows (under about 750px tall, e.g. a laptop browser): lift the first-screen text a little (its top is 15% of the stage) so its buttons and the loading line stay clear of the bar. */
 .stage-copy{top:calc(15% - clamp(0px,640px - 85vh,72px))}
}
