/* ============================================================
   AI-GHS · layout.css — 应用页响应式唯一真源（统一自适应方案）
   引入方式：<link rel="stylesheet" href="/assets/layout.css">（紧跟 sk-tokens.css）
   配套：/assets/layout.js 把两条固定底栏的**实测高度**写进 --sk-tabnav-h / --sk-bottombar-h

   ── 契约（本文件是下列量的唯一真源；页面里一律不得再各自写死） ──
     容器宽度    body / .app / .page / .page-wrap  →  var(--sk-app-container)
                 移动端 480px；≥768px 桌面端 960px
     底部导航栏  nav.sk-tabbar                      →  同宽
     底部操作栏  .bottom-bar                        →  同宽
     底栏几何    .bottom-bar 紧贴 nav.sk-tabbar 上沿，缝隙 = var(--sk-bar-gap) = 0
     滚动预留    .page-scroll { padding-bottom: 导航栏 + 操作栏 + 8px }

   ── ⚠️ 边界声明（规则 H：工具的边界必须写进工具本体） ──
   本文件只作用于「应用内页」：
     home / profile / report-list / report-detail / progress / planning（+ login/register 仅取宽度，
     它们没有底栏，加本文件对其视觉零影响：视口 ≤480px 时 body 宽度不变；≥768px 时
     .auth-card / .site-foot 自身 max-width:420px 居中，body 变宽不改变它们的居中位置）。
   文档页 about / privacy / terms、营销页 index.html、后台 admin*.html
     **不引用本文件**。它们走 base.css 的 --sk-container（1200px）体系；
     若给它们套上 --sk-app-container，≥768px 时整个外框会由 1200px 压到 960px，
     与同样停留在 1200px 的 index.html 之间**制造出新的不一致**（本轮实测依据见报告 §3）。
   ============================================================ */

:root {
  /* 应用内容器宽度：唯一真源。移动 480 / 桌面 960（沿用 @media (min-width:768px) 断点） */
  --sk-app-container: 480px;

  /* 两条固定底栏的实测高度。layout.js 用真实测量值覆写；
     下面两个值只是「JS 未执行 / 元素尚未渲染」时的兜底，
     且与改版前各页写死的值一致（56px / 73px）⇒ JS 失效时行为不比改版前差。 */
  --sk-tabnav-h: 56px;
  --sk-bottombar-h: 73px;

  /* 两条固定栏之间的缝隙：契约要求恒为 0。
     写成变量是为了让这个「0」可被单独读出与断言，而不是散落在各页的算式里。 */
  --sk-bar-gap: 0px;
}

@media (min-width: 768px) {
  :root { --sk-app-container: 960px; }
}

/* ---- 1. 容器宽度：所有等价选择器 → 同一宽度、同一居中方式 ----
   body 只加左右 auto（不用 margin 简写），避免覆盖各页自己的上下外边距。 */
body,
.app,
.page,
.page-wrap {
  max-width: var(--sk-app-container);
  margin-left: auto;
  margin-right: auto;
}

/* ---- 2. 两条固定底栏与容器同宽 ----
   nav.sk-tabbar 用「元素 + 类」= (0,1,1)，而不是 .sk-tabbar = (0,1,0)：
   nav.js 会往 <head> 末尾注入 .sk-tabbar{max-width:480px} 与
   @media(min-width:768px){.sk-tabbar{max-width:720px}}；注入点在本文件之后，
   同等优先级下本文件必输 —— 提高优先级是这里唯一有效的做法。
   （nav.js 是内容被钉文件，一个字节都不能改，所以只能从 CSS 侧压过它。） */
.bottom-bar,
nav.sk-tabbar {
  max-width: var(--sk-app-container);
}

/* ---- 3. 底栏几何：操作栏紧贴导航栏上沿（缝隙 = --sk-bar-gap = 0）----
   --sk-tabnav-h 是 nav.sk-tabbar 的实测高度，含 env(safe-area-inset-bottom)，
   与 nav.js 的 height:calc(56px + env(safe-area-inset-bottom)) 同口径。
   没有底部导航的页面由 layout.js 显式置 0px ⇒ 操作栏落到视口底，不吃 56px 兜底值。 */
.bottom-bar {
  bottom: calc(var(--sk-tabnav-h) + var(--sk-bar-gap));
}

/* ---- 4. 可选结构：固定头部 + 内层滚动 ----
   开启方式（三件都要有，缺一不开）：
     <html class="sk-fixed-shell">  +  <div class="page">  +  <div class="page-scroll" id="pageScroll">
   本轮唯一采用者是 planning.html。其余应用页**保留整页滚动**（它们的 markup 里根本没有
   内层滚动容器），因此不带 .sk-fixed-shell ⇒ 下面第一条规则对它们零影响。 */
html.sk-fixed-shell,
html.sk-fixed-shell body {
  height: 100%;
  overflow: hidden;
}

html.sk-fixed-shell .page {
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 唯一的滚动层：底部预留 = 导航栏 + 操作栏 + 8px 呼吸位（不再靠猜的数字） */
.page-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: calc(var(--sk-tabnav-h) + var(--sk-bottombar-h) + 8px);
}
