/* Anchor the normal frame to the actual viewport edges, not a vh-derived height.
   Under cover, reserve the top inset once at the frame boundary.
   The bottom inset belongs only inside the border-box dock, never the body. */
:root { --app-safe-top:env(safe-area-inset-top,0px); --dock-gesture-inset:env(safe-area-inset-bottom,0px); }
html { height:100%; overflow:hidden; background:#0b191e; }
body { position:relative; margin:0; padding:0; min-height:0; height:100%; overflow:hidden; }
#appFrame {
  position:fixed; top:var(--app-safe-top); bottom:0; left:0; width:100%; min-height:0;
  height:auto;
  display:grid; grid-template-rows:auto minmax(0,1fr) calc(68px + var(--dock-gesture-inset));
  overflow:hidden;
}
.shell-head { position:absolute; top:8px; }
.chapterbar { grid-row:1; width:100%; padding-top:8px; }
#screenViewport { grid-row:2; min-height:0; overflow:auto; overscroll-behavior-y:contain; }
#dockLayer { grid-row:3; position:relative; height:calc(68px + var(--dock-gesture-inset)); padding-bottom:var(--dock-gesture-inset); width:100%; background:#0b191e; border-top:1px solid #42575b; z-index:80; }
#expeditionNav {
  position:static; inset:auto; transform:none; margin:0 auto;
  width:min(100%,720px); height:67px; padding:3px 10px;
  border:0; border-radius:0; box-shadow:none; background:none;
  backdrop-filter:none; -webkit-backdrop-filter:none;
}
body[data-screen="home"] #home, #hutHome { height:100%; min-height:0; padding-bottom:10px; }
#workspace { min-height:0; }
.training-feature .app-shell:has(.adventure-landscape) { padding-bottom:0; }
/* Allow accessible scrolling if text zoom or a keyboard makes content taller;
   normal-sized main screens fit naturally without clipping overflow. */
body[data-screen="home"] #screenViewport, body[data-screen="hutHome"] #screenViewport { overflow:auto; }
.nutrition-feature .ov { max-height:var(--app-viewport-height,100dvh); }

/* iOS Home Screen cold starts can report a viewport shorter by the status bar.
   In standalone only, the large viewport is the full app surface. Keep the
   root/frame in document flow: a fixed containing block can retain the shorter
   WebKit viewport even when the content height is corrected.
   navigator.standalone detection in viewport.js also covers unreliable media queries. */
:root[data-ios-standalone="true"] {
  --app-layout-height:100vh;
  --app-layout-height:100lvh;
  height:var(--app-layout-height);
}
:root[data-ios-standalone="true"] body { height:100%; padding-top:var(--app-safe-top); }
:root[data-ios-standalone="true"] #appFrame {
  position:relative; top:auto; bottom:auto;
  height:calc(var(--app-layout-height) - var(--app-safe-top));
}

/* The keyboard owns the bottom of the screen. Do not reserve a second dock gap. */
:root[data-keyboard-open="true"] { --app-safe-top:0px; height:var(--app-viewport-height,100dvh); }
:root[data-keyboard-open="true"] #appFrame { position:absolute; top:var(--app-viewport-top,0px); bottom:auto; height:var(--app-viewport-height,100dvh); grid-template-rows:auto minmax(0,1fr); }
:root[data-keyboard-open="true"] #dockLayer { display:none; }
:root[data-keyboard-open="true"] #screenViewport { scroll-padding-block:16px 24px; }
:root[data-keyboard-open="true"] dialog[open] { top:var(--app-viewport-top,0px); bottom:auto; margin:8px auto; max-height:calc(var(--app-viewport-height,100dvh) - 16px); }

/* Remove native button padding and inline-SVG baseline spacing. */
#chapterInfo { display:grid; place-items:center; padding:0; line-height:1; }
#chapterInfo svg { display:block; flex-shrink:0; }
