/* ==========================================================================
   PAGES 多设备适配补丁层  ·  responsive.css
   --------------------------------------------------------------------------
   设计原则（三条硬约束）：
     1. 只覆盖，不重命名 —— 不改任何既有 class / id / CSS 变量名。
        （部分页面用 getComputedStyle 读 CSS 变量喂 canvas，改名会静默画错）
     2. 全部写在既有样式之后，且尽量用 @media 收窄作用域 —— 桌面端必须像素级不变。
     3. 纯增量，不改既有的任何选择器本体。

   生效方式：在每个页面 <head> 末尾、既有 <style> 之后引入本文件。
   另需配合 responsive-inject.py 写入的 <head> meta（theme-color / viewport-fit）
   与 <body> 上的 --rs-top-h 内联变量。

   目录：
     1. 兜底：横向溢出 / 媒体元素
     2. 表格：小屏救活（不依赖手写 .table-wrap）
     3. 表单：iOS 聚焦自动放大
     4. 触摸：目标尺寸 / 悬停降级
     5. 可访问性：焦点可见 / 动效降级 / 高对比
     6. 视口：dvh 兜底 / 安全区（刘海屏）
     7. 横屏（手机横置）
     8. 容器查询增强（支持的浏览器生效）
     9. 打印
   ========================================================================== */

/* ==========================================================================
   1. 兜底：横向溢出 / 媒体元素
   --------------------------------------------------------------------------
   站内多页 body{overflow-x:hidden}，会把溢出"藏起来"而不是修好 ——
   结果是内容被裁掉且用户无法横滑。这里给媒体元素加上限，并为 pre 提供滚动。
   ========================================================================== */
html { max-width: 100%; }
body { max-width: 100%; }

img, svg, video, canvas, iframe, embed, object {
  max-width: 100%;
}
/* canvas 保持自身宽高比，避免被 max-width 压扁 */
canvas { height: auto; }

/* 代码块 / 长字符串：在窄屏可横滑而不是撑破布局 */
pre {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
pre > code { white-space: pre; }
code, kbd, samp { word-break: break-word; }

/* 超长无空格串（URL、哈希、英文单词）
   —— 白箱页的因果链哈希、审计页的证据 ID 在手机上会撑破卡片 */
.pill, .pill-tag, .tag, .badge, .hash, .mono, code {
  overflow-wrap: anywhere;
}

/* ==========================================================================
   2. 表格：小屏救活
   --------------------------------------------------------------------------
   现状：table{min-width:560|640|720px}，但 5 个 guide 页 / docs/index / ai-draw
   的滚动容器严重缺失（docs/guide.html 27 张表只有 2 个 .table-wrap）。
   下面用「后置 + 只覆盖 overflow/min-width」的方式给所有表格兜底，
   并显式禁止 table 自身参与横向溢出，交由包裹层滚动。
   ========================================================================== */

@media (max-width: 1024px) {
  /* 有手写容器的：确保它们真的能滚 */
  .table-wrap,
  .table-scroll,
  [class*="table-wrap"] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* 滚动提示：右侧渐隐，暗示"还能往右滑" */
    background-image: linear-gradient(to left, rgba(0, 0, 0, .06), rgba(0, 0, 0, 0) 14px);
    background-position: right center;
    background-repeat: no-repeat;
    background-size: 14px 100%;
  }

  /* 没有手写容器的：把表格自身变成块级横滑容器。
     不使用 *:has(> table) 或直接子选择器，避免影响既定布局。 */
  table {
    display: block;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* 关键：解除固定最小宽度，否则父级被撑破 */
    min-width: 0;
  }
  /* 表格内部单元格仍按内容排布，保持表格语义与列对齐 */
  table > thead,
  table > tbody,
  table > tfoot { display: table; width: 100%; }
}

@media (max-width: 640px) {
  /* 手机竖屏：收紧表格内边距，换取更多可用列宽 */
  table { font-size: 12.5px; }
  table th, table td { padding-left: 8px; padding-right: 8px; }
}

/* ==========================================================================
   3. 表单：iOS 聚焦自动放大
   --------------------------------------------------------------------------
   iOS Safari 对字号 < 16px 的 input/select/textarea 会在聚焦时放大整页且不还原。
   站内 ai-draw 有 49 个输入元素、74 条 13–15px 字号规则，是最严重的一处。
   仅在触屏 + 窄屏生效，桌面视觉完全不变。
   ========================================================================== */
@media (max-width: 768px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  select,
  textarea {
    font-size: 16px;
  }
}

/* 触屏设备上的交互元素也补一份（不依赖屏宽，覆盖平板） */
@media (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  select,
  textarea {
    font-size: max(16px, 1em);
  }
}

/* ==========================================================================
   4. 触摸：目标尺寸 / 悬停降级
   ========================================================================== */

/* 4.1 触摸目标 ≥44px（Apple HIG）——仅在指针粗糙（触屏）时生效，
       桌面鼠标环境完全不受影响 */
@media (pointer: coarse) {
  button,
  [role="button"],
  .btn,
  .btn-quiet,
  .icon-btn,
  .pill,
  .pill-tag,
  .tag,
  summary,
  a.btn,
  nav a,
  .nav-links a,
  .back-btn,
  .lang-btn,
  .deep-btn {
    min-height: 44px;
  }
  /* 行内小链接（正文里的锚点）不强制撑高，只保证可点区域 */
  .doc p a, article p a { min-height: 0; }

  /* 表单控件同样保证高度，避免手机上误触 */
  input:not([type="checkbox"]):not([type="radio"]), select, textarea {
    min-height: 44px;
  }
}

/* 4.2 悬停降级：站内 10–34 处 :hover 承担了信息传达（如缩略图卡的
       "打开 →" 只有 hover 才高亮），触屏拿不到。此处让关键信息常显。 */
@media (hover: none) {
  /* 缩略图 / 卡片上的行动点：常显描边，不再依赖悬停 */
  .thumb-cap .go,
  .card-actions a,
  .card-actions button {
    color: var(--gold-deep, #9a7a32);
    border-color: var(--gold, #b8943f);
    background: rgba(184, 148, 63, .08);
  }
  .thumb { transform: none; }

  /* 顶栏按钮在触摸设备上给一点常驻可见性，否则像"禁用态" */
  .nav-cta { background: var(--gold, #b8943f); color: #fff; }
}

/* ==========================================================================
   5. 可访问性
   ========================================================================== */

/* 5.1 键盘焦点可见（站内 0/16 页有 :focus-visible） */
:focus-visible {
  outline: 2px solid var(--accent, var(--gold, var(--primary, #0052ff)));
  outline-offset: 2px;
  border-radius: 4px;
}
/* 鼠标点击不出现焦点环，避免破坏现有视觉 */
:focus:not(:focus-visible) { outline: none; }

/* 5.2 动效降级（站内仅 demo.html 有 2 处）
       覆盖 aurora 漂浮、reveal 进场、canvas 脉冲、count-up 等。
       注意：不能用 0s，否则会跳过 transitionend 回调；0.01ms 既几乎无动效
       又能正常触发事件。
       scroll-behavior 单独在末尾还原为 auto —— 平滑滚动本身也是动效。 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  /* 滚动进场动画的终态：直接显示，不要停在 opacity:0 */
  .reveal { opacity: 1 !important; transform: none !important; }
  html { scroll-behavior: auto !important; }
}

/* 5.3 强制高对比模式：描边补足 */
@media (forced-colors: active) {
  button, .btn, .card, nav, .topnav, .topbar { border: 1px solid ButtonText; }
}

/* 5.4 跳转到主内容（纯新增，不影响任何既有元素）
       加了 tabindex 的 #main 之前不会响应，因此默认视觉隐藏，聚焦后出现。 */
.rs-skip {
  position: fixed;
  top: -100px;
  left: 12px;
  z-index: 9999;
  padding: 10px 18px;
  border-radius: 0 0 8px 8px;
  background: var(--accent, var(--gold, #0052ff));
  color: #fff;
  font-size: 14px;
  text-decoration: none;
  transition: top .15s ease;
}
.rs-skip:focus { top: 0; }

/* ==========================================================================
   6. 视口：dvh 兜底 / 安全区
   ========================================================================== */

/* 6.1 移动端地址栏收缩会导致 100vh 突变、内容跳动（index.html:91 .hero）。
       老浏览器忽略 dvh 那一行，保持原状，不会退化。 */
.hero {
  min-height: 100vh;
  min-height: 100dvh;
}
/* 全屏型容器同样兜底 */
[style*="100vh"] { --rs-vh-fallback: 1; }

/* 6.2 安全区（刘海屏 / 灵动岛 / 底部 Home 条）
       ------------------------------------------------------------------
       门控：全部规则都要求 <html class="rs-has-inset">，该类由 responsive.js
       在「探针测出设备安全区存在」时才添加。桌面/无刘海设备永远没有这个类，
       因此以下规则一条都不会参与计算 —— 桌面像素级不变（这是可验证的承诺）。

       写法要点：**绝不覆盖**原有内边距，一律「原值 + 安全区」相加。
       各页顶栏的原始 padding-top / height 差异很大（nav=18px、
       soulmate/.topbar=14px、audit/tax-audit 内侧=.topbar 14px、
       virtual-world nav=10px、guides .topnav=0+52px、docs .topnav=0+56px），
       所以由 JS 现场量出真实原值写入 --rs-*-pt / -pl / -pr / -h，
       未声明时回落 0px/52px，保证不写错。
       ------------------------------------------------------------------ */

/* (a) 固定/吸顶顶栏：内边距叠加，不覆盖 */
.rs-has-inset nav {
  padding-top: calc(var(--rs-nav-pt, 0px) + env(safe-area-inset-top, 0px));
  padding-left: calc(var(--rs-nav-pl, 0px) + env(safe-area-inset-left, 0px));
  padding-right: calc(var(--rs-nav-pr, 0px) + env(safe-area-inset-right, 0px));
}
.rs-has-inset .topnav {
  padding-top: calc(var(--rs-topnav-pt, 0px) + env(safe-area-inset-top, 0px));
  padding-left: calc(var(--rs-topnav-pl, 0px) + env(safe-area-inset-left, 0px));
  padding-right: calc(var(--rs-topnav-pr, 0px) + env(safe-area-inset-right, 0px));
  /* 52px / 56px 固定高：高度必须同步加高，否则内容被裁 */
  height: calc(var(--rs-topnav-h, 52px) + env(safe-area-inset-top, 0px));
  box-sizing: border-box;
}
.rs-has-inset .topbar {
  padding-top: calc(var(--rs-topbar-pt, 0px) + env(safe-area-inset-top, 0px));
}
/* 只有「高度被显式写死」的顶栏才同步加高（audit / tax-audit，高 var(--top-h)）。
   your-soulmate 的顶栏是 auto 高度，会自动撑开，绝不能给它写 calc(auto + …)。 */
.rs-has-inset body.rs-bar-h .topbar {
  height: calc(var(--rs-topbar-h, var(--top-h, 56px)) + env(safe-area-inset-top, 0px));
  box-sizing: border-box;
}
/* 顶栏内部元素一并避开横屏刘海 */
.rs-has-inset .topnav .brand,
.rs-has-inset .topbar-title { margin-left: env(safe-area-inset-left, 0px); }

/* (b) 底部固定元素：避开 Home 条 / 手势条 */
.rs-has-inset footer,
.rs-has-inset .footer,
.rs-has-inset .side-status,
.rs-has-inset .side-foot {
  padding-bottom: calc(var(--rs-footer-pb, 0px) + env(safe-area-inset-bottom, 0px));
}
/* embed 模式的浮动返回按钮：避开刘海 */
.rs-has-inset body.embed #embedBackBtn {
  right: calc(14px + env(safe-area-inset-right, 0px));
  top: calc(14px + env(safe-area-inset-top, 0px));
}

/* (c) 移动抽屉 / 文档目录：横屏刘海会遮住左右 */
.rs-has-inset .sidebar {
  padding-left: calc(var(--rs-sidebar-pl, 13px) + env(safe-area-inset-left, 0px));
}
.rs-has-inset aside.toc {
  padding-left: calc(var(--rs-toc-pl, 0px) + env(safe-area-inset-left, 0px));
}

/* ==========================================================================
   7. 横屏（手机横置）
   --------------------------------------------------------------------------
   手机横屏可用高度往往只有 320–430px，首屏 hero 与固定顶栏会挤爆。
   ========================================================================== */
@media (orientation: landscape) and (max-height: 500px) {
  /* hero 类首屏：压缩上下留白，保证首屏能看到主内容 */
  .hero {
    min-height: auto;
    padding-top: calc(72px + env(safe-area-inset-top, 0px));
    padding-bottom: 48px;
  }
  /* 大标题在横屏不必撑满 */
  .hero h1 { font-size: clamp(30px, 7vh, 54px); }
  h1 { font-size: clamp(28px, 8vh, 48px); }

  /* 段落间距收紧，横屏一屏能看到更多 */
  section { padding-top: 56px; padding-bottom: 56px; }

  /* 文档页目录在横屏改为可滚动，避免被截断 */
  aside.toc { max-height: calc(100vh - env(safe-area-inset-top, 0px)); overflow-y: auto; }

  /* 悬浮面板 / 弹层：限制高度，避免顶到刘海 */
  .modal, .dialog, [class*="modal"], [class*="dialog"] {
    max-height: calc(100dvh - env(safe-area-inset-top, 0px) - 16px);
    overflow-y: auto;
  }
}

/* 手机横屏下过高的 iframe（demo.html 的 620px 演示框） */
@media (orientation: landscape) and (max-height: 560px) {
  iframe { max-height: calc(100dvh - 24px); }
}

/* ==========================================================================
   8. 布局结构修复：audit / tax-audit 的「侧栏吃掉正文」
   --------------------------------------------------------------------------
   这两页的结构是：
       .app{display:flex}  +  .side{position:fixed; inset:0 auto 0 0; width:236px}
                           +  .main{flex:1; margin-left:236px}
   问题（桌面宽屏下就已存在，窄屏下变为致命）：
     · .side 是 fixed，脱离文档流 → .app 里唯一的流内子元素只有 .main
     · .main 拿到「整页宽」，又被 margin-left:236px 推出去
       → 右边界 = 236 + 视口宽  → 页面横向溢出 246px（实测 tax-audit@768）
     · 跳到 ≤900px 时，.side 改成 position:relative; width:100%
       → 侧栏占满一行，.main 被挤成 0px 宽 → **手机上看不到正文**
       实测：audit@375/768/900、tax-audit@320/375

   修法：窄屏下让 .side 与 .main 回归普通的块级上下堆叠。
   桌面（≥901px）不做任何改动，像素级不变。
   ========================================================================== */
@media (max-width: 900px) {
  /* 不用 flex-direction:column —— 那会让 .main{flex:1}（= flex-basis:0%）
     在纵轴上按高度生效，可能把内容压成 0 高。block 最可预测。 */
  .app {
    display: block;
    min-height: 0;
  }
  .side {
    width: auto;
    max-width: none;
  }
  .main {
    margin-left: 0;
    width: 100%;
    min-width: 0;
  }
  .content {
    width: 100%;
    max-width: 100%;
  }
}

/* ==========================================================================
   9. 容器查询增强（仅支持的浏览器生效，不支持则完全忽略）
   --------------------------------------------------------------------------
   卡片/面板按「自身宽度」响应，比按整页宽度更准确 —— 尤其适合
   your-soulmate 白箱三列、ai-draw 表单网格这类嵌在侧栏里的区域。
   ========================================================================== */
@supports (container-type: inline-size) {
  .card,
  .glass,
  .panel,
  .stat-card,
  .subsys-card,
  .scale-card {
    container-type: inline-size;
  }

  /* 窄卡片内：多列网格压成一列，长标题换行 */
  @container (max-width: 420px) {
    .card h3,
    .stat-card h3 { font-size: 15px; }
    .card .row,
    .stat-card .row { flex-direction: column; align-items: flex-start; }
  }
}

/* ==========================================================================
   10. 打印
   ========================================================================== */
@media print {
  nav, .topnav, .topbar, .sidebar, .side-scrim, aside.toc,
  .rs-skip, .table-wrap::after { display: none !important; }
  main, .doc, .content { margin: 0 !important; padding: 0 !important; max-width: none !important; }
  table { min-width: 0 !important; font-size: 10pt; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #666; }
}

/* ==========================================================================
   11. 移动端导航抽屉（配合 assets/nav-drawer.js）
   --------------------------------------------------------------------------
   仅 ≤900px 生效。桌面端 .rs-burger 恒为 display:none，不产生任何可见元素，
   因此不影响桌面像素。汉堡由 JS 注入，本段只管外观与展开态。
   ========================================================================== */
.rs-burger { display: none; }
.rs-nav-scrim {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 44;
  background: rgba(8, 12, 20, .45);
}

@media (max-width: 900px) {
  .rs-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    min-width: 40px;
    margin-left: 10px;
    padding: 0;
    flex: 0 0 auto;
    border-radius: 9px;
    background: var(--glass, rgba(15, 23, 42, .04));
    border: 1px solid var(--glass-border, rgba(15, 23, 42, .12));
    color: inherit;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
  }
  .rs-burger:active { transform: scale(.96); }

  body.rs-nav-open { overflow: hidden; }
  body.rs-nav-open .rs-nav-scrim { display: block; }

  /* (a) <nav> 内 .nav-links：整屏下拉面板（fixed，规避 nav 自身定位/层级差异） */
  body.rs-nav-open nav .nav-links {
    display: flex !important;
    flex-direction: column;
    gap: 0;
    position: fixed;
    inset: 0;
    z-index: 45;
    padding: calc(var(--rs-nav-h, 64px) + 10px) 0 28px;
    background: rgba(253, 253, 251, .985);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
    overflow-y: auto;
  }
  body.rs-nav-open nav .nav-links a {
    font-size: 16px;
    padding: 14px 24px;
    letter-spacing: .04em;
  }
  body.rs-nav-open nav .nav-links a::after { display: none; }

  /* (b) virtual-world 型：nav 内一排 a.btn 逐行展开 */
  body.rs-nav-open nav { flex-wrap: wrap; }
  body.rs-nav-open nav a.btn {
    display: block !important;
    flex: 1 1 100%;
    text-align: left;
    padding: 12px 22px;
  }

  /* (c) ai-draw 型：被 display:none 的侧栏回归为左侧抽屉 */
  body.rs-nav-open .sidebar {
    display: flex !important;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 45;
    width: min(82vw, 300px);
    box-shadow: 0 0 60px -10px rgba(0, 0, 0, .5);
    overflow-y: auto;
  }
}
