/* ============================================================
   benben 骨架层响应式  (P0 · 2026-10-15)
   ------------------------------------------------------------
   范围：只处理骨架 3 处 —— sidebar / topbar / content-wrapper。
        桌面菜单项的字体大小**不覆盖**（见「二」，沿用 SB Admin 2 初始值）。
        页面内容（各业务模板）不在本文件处理，属 P2 范围。

   桌面（>= 768px）：**视觉与现状保持一致**，仅做去字体依赖的清理。
   移动（< 768px）：SB Admin 2 原方案是「6.5rem 图标条 + .65rem 小字」
                    紧贴左侧，占 375px 屏宽的 28%，观感与可用性都差。
                    本文件将其改为**全宽抽屉**（256px，滑入 + 遮罩）。

   落地路径：static/stock/css/responsive.css
   引入位置：templates/dashboard/resources_head.html（tokens.css 之后）
   ============================================================ */

/* ------------------------------------------------------------
   一、骨架层箭头纯 CSS 化（去掉 Font Awesome 字体依赖）
   SB Admin 2 原用 fa-chevron 的 content 码点（\f104/\f105/\f107），
   无 FA 字体时渲染为方块。此处改为 CSS 边框绘制，视觉等价。
   ------------------------------------------------------------ */
.sidebar #sidebarToggle::after {
  font-family: inherit !important;
  font-weight: 400 !important;
  content: '' !important;
  display: inline-block;
  width: .45rem;
  height: .45rem;
  border-left: 2px solid rgba(255, 255, 255, .75);
  border-bottom: 2px solid rgba(255, 255, 255, .75);
  transform: rotate(45deg) translate(1px, -1px);
}
.sidebar.toggled #sidebarToggle::after {
  content: '' !important;
  font-family: inherit !important;
  margin-left: 0;
  transform: rotate(-135deg) translate(1px, -1px);
}

/* 2026-10-15 修：原此处有 `border: 0 !important;`，属简写 + !important，
   按 CSS 规范 !important 声明优先于普通声明、与源码顺序无关，会把紧随其后的
   border-right / border-bottom 一并压成 0 ⇒ 箭头渲染为 0 边框、完全不可见，
   导致有二级菜单的项与直连项外观无法区分。删掉该行即可（SB Admin 2 自带的
   border:0 不带 !important 且本文件最后加载，不会反向覆盖）。 */
/* 2026-10-15 修（垂直对齐）：SB Admin 2 原规则用 \f107 字形 + 1rem 高盒子，
   浮动到行盒顶部仍近似居中；我们换成边框画的 .4rem 小方块后盒子骤矮，
   浮动到顶部即明显偏高（实测箭头墨迹中线 18.0px vs 文字 30.0px，偏高 12px）。
   改为绝对定位 + translateY(-50%) 精确垂直居中，不再依赖浮动与行盒高度。
   ⚠️ 对齐目标是「文字墨迹视觉重心」，不是「元素几何中心」：CJK 字形墨迹比行盒
   几何中心低，旋转方块的渲染包围盒也比几何中心略低，两者叠加后实测只需补 1px
   ——桌面残差 -0.17px、移动端 +0.33px（均为像素级实测，非估算）。 */
.sidebar .nav-item .nav-link {
  position: relative;            /* 作为箭头的定位参照 */
}
.sidebar .nav-item .nav-link[data-toggle="collapse"]::after {
  font-family: inherit !important;
  content: '' !important;
  position: absolute;
  top: calc(50% + 1px);          /* 垂直居中 + 1px 视觉补偿（实测校准） */
  right: 1rem;                   /* 与桌面 padding: 1rem 对齐 */
  margin: 0;                     /* 清掉旧的浮动位移 */
  width: .4rem;
  height: .4rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
  opacity: .65;
}
.sidebar .nav-item .nav-link[data-toggle="collapse"].collapsed::after {
  content: '' !important;
  transform: translateY(-50%) rotate(-45deg);
}

/* ------------------------------------------------------------
   二、桌面菜单项的字体大小：**不覆盖，沿用 SB Admin 2 初始值**（2026-10-15 回退）
   ------------------------------------------------------------
   2026-10-15 曾在桌面段把图标调到 1.05rem / 槽 1.5rem / 间距 8px，并把折叠态
   标签从 .65rem 拉到 .85rem，想做「两态统一 + 图标放大 + 标签右移」。用户反馈
   「越改越难看了」，遂整段回退，这里只保留记录，不再有任何声明。

   回退后生效的就是 sb-admin-2.min.css 的原始取值：
     · 桌面展开态 ≥768px（sb-admin-2.css:10534-10548）
         nav-link  padding:1rem; width:14rem; text-align:left
         i         font-size:.85rem（13.6px）；margin-right:.25rem（4px）
         span      font-size:.85rem（13.6px）；display:inline
     · 桌面折叠态 .sidebar.toggled（sb-admin-2.css:10602-10613）
         nav-link  padding:.75rem 1rem; width:6.5rem; text-align:center
         i         margin-right:0（字号不覆盖 ⇒ 仍是 .85rem）
         span      font-size:.65rem（10.4px）；display:block
   即：**图标两态都是 13.6px，标签展开 13.6px / 折叠 10.4px** —— 折叠后标签变小
   是 SB Admin 2 的原始设计，不再「修正」。

   ⚠️ 想再动菜单字号时的两条约束（都是踩过的坑）：
     ① `i` 若只改 font-size 而不设 line-height:1，1.05rem×1.5 的 inline box
        (25.2px) 会顶高行盒，行高 56 → 57.19px 并逐行累积，整条菜单的纵向
        节奏与箭头参照盒都会跟着变。
     ② `.sidebar.toggled .nav-item .nav-link span` 与 SB Admin 2 原规则同为
        4 个 class 优先级，只能靠源码顺序取胜（本文件后加载）。
   ------------------------------------------------------------ */

/* ============================================================
   三、移动端（< 768px）：侧栏改全宽抽屉
   ============================================================ */
@media (max-width: 767.98px) {

  /* ① 中和 SB Admin 2 的移动端紧凑规则
        （.sidebar.toggled 覆盖 sb-admin-2.js 在 <480px 自动加的 toggled）
     ⚠️ 本选择器块**禁止任何合成层提升手段**（2026-10-16 第四轮定案）：
        will-change / backface-visibility / -webkit-overflow-scrolling:touch
        都会把「fixed + overflow-y:auto」的抽屉强制提升为合成滚动层，
        展开二级菜单改变内容高度 ⇒ iOS 对整层重新栅格化，新露出区域
        短暂未上屏 = 用户看到的「白色区域闪一下」。抽屉滑入动画由
        transform 过渡驱动，动画期间浏览器本来就会合成它，动画结束后
        回归普通绘制——二级菜单展开时不再触发整层重栅格化。
        历史教训：第一轮删了 touch-scrolling 却同时加了 will-change，
        抽屉始终没离开合成层，等于什么都没改（连续三轮真机复测为证）。 */
  .sidebar,
  .sidebar.toggled {
    width: var(--bb-drawer-w) !important;   /* 16rem = 256px */
    height: 100vh;
    overflow-x: hidden;
    overflow-y: auto;
  }

  /* ② 抽屉定位：固定 + 默认移出屏幕 */
  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 1045;
    transform: translateX(-100%);
    transition: transform var(--bb-transition);
  }

  /* ③ 打开态 */
  body.bb-drawer-open .sidebar {
    transform: translateX(0);
    box-shadow: var(--bb-shadow-md);
  }

  /* ④ 打开时锁定背景滚动 */
  body.bb-drawer-open {
    overflow: hidden;
  }

  /* ⑤ 遮罩 */
  .bb-drawer-backdrop {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1040;
    background: rgba(58, 59, 69, .45);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--bb-transition), visibility var(--bb-transition);
  }
  body.bb-drawer-open .bb-drawer-backdrop {
    opacity: 1;
    visibility: visible;
  }

  /* ⑥ 菜单项：恢复左对齐、可读字号、触摸友好高度 */
  .sidebar .nav-item .nav-link {
    width: 100% !important;
    display: flex;
    align-items: center;
    text-align: left;
    padding: var(--bb-sp-3) var(--bb-sp-5);
    min-height: var(--bb-touch-min);
  }
  .sidebar .nav-item .nav-link i {
    /* ⚠️ 移动端取 1.05rem，**不是** SB Admin 2 初始值 —— 本段是整个「全宽抽屉」
       自建 UI 的一部分（SB2 移动端是 6.5rem 图标条 + .65rem 小字 + 居中），
       在 256px 抽屉里没有可比性，故不套用桌面段的回退结论。
       原值 1.25rem + .7rem 是从抽屉改造前的 flex 布局折算来的，非设计取值。 */
    font-size: 1.05rem;
    width: 1.5rem;
    margin-right: var(--bb-sp-2);
    text-align: center;
  }
  .sidebar .nav-item .nav-link span {
    display: inline;
    font-size: .95rem;          /* 原 .65rem（≈10.4px）过小 */
  }
  /* 箭头：绝对定位后水平位置改用 right 表达（= 原 flex 的 margin-right .2rem）；
     垂直向沿用基规则的 calc(50% + 1px)，实测两端残差均 ≤0.35px */
  .sidebar .nav-item .nav-link[data-toggle="collapse"]::after {
    right: calc(var(--bb-sp-5) + .2rem);
  }

  /* ⑦ 品牌区：文字回归 + 左对齐 */
  .sidebar .sidebar-brand {
    justify-content: flex-start !important;
    text-transform: none;
    padding: var(--bb-sp-4) var(--bb-sp-5);
    font-size: 1.05rem;
  }
  .sidebar .sidebar-brand .sidebar-brand-text {
    display: inline;
  }

  /* ⑧ 分组标题左对齐 */
  .sidebar .sidebar-heading {
    text-align: left;
    padding: 0 var(--bb-sp-5);
    font-size: var(--bb-fs-xs);
  }

  /* ⑨ 子菜单内联展开（原为 absolute 浮层，小屏下定位尴尬）
     🔴 必须显式关掉 SB2 基座的 growIn 入场动画（2026-10-16 第五轮 · 白闪真凶）：
     SB Admin 2 侧栏有**双形态**，growIn 的开关是错位的——
       · ≥768px 正常侧栏（桌面）：:10519 写了 `animation: none`  ⇒ 无动画、不闪；
       · ≥768px 折叠图标条 .sidebar.toggled：:10575 挂 growIn 200ms；
       · <768px 基座（手机）：:9866 `.sidebar .nav-item .collapse` 同样挂
         growIn 200ms，且**没有任何媒体查询关掉它**。
     我们既然把移动端改成内联展开（不再是浮层），就该和桌面展开态一样无入场动画；
     漏掉这一步的代价 = 每次展开都播一遍 growIn：`scale(0.9)+opacity:0 → scale(1)+opacity:1`，
     而 opacity 的缓动是 `cubic-bezier(0, 1, 0.4, 1)`（首控制点 y=1，开局即冲到接近 1），
     深色抽屉里的白色面板由此在十几毫秒内从全透明跳到几乎全不透明 = 用户看到的
     「白色区域闪一下」。实测（375px，rAF 逐帧）：修复前面板 opacity 出现
     0.000→0.071→0.221→0.409→0.576 共 13 帧半透明 + 14 帧 transform；桌面 0 帧。
     ⚠️ 这解释了此前四轮修复（transition 时长 / 面板 translateZ / 抽屉合成层）
     为何全部无效——它们改的都是 transition 与图层，从未碰 `animation`。
     ⚠️ 实测确认后代（.collapse-inner）computed opacity 恒为 1：动画作用在 .collapse 上，
     排查时必须查**父级**而不是面板本身。 */
  .sidebar .nav-item .collapse {
    position: static !important;
    left: auto !important;
    top: auto !important;
    -webkit-animation: none !important;
    animation: none !important;
  }
  .sidebar .nav-item .collapsing {
    display: block;
    transition: height .15s ease;
  }
  /* 🔴🔴 本段所有面板规则必须**成对**写 `.collapse` + `.collapsing`（2026-10-16 第六轮）：
     Bootstrap 4 展开时先 `classList.remove('collapse')` 再 `add('collapsing')`，
     高度过渡的这 150ms 内元素**根本没有 .collapse 类** ⇒ 只写 .collapse 的规则
     在这段时间全部失效，而 SB2 :10367 成对规则的 `.5rem 0` padding +
     `0 0 1rem 0` margin 反而生效。
     实测（375px，rAF 逐帧采样 .collapse/.collapse-inner/.collapse-header）：
       · 过渡期间首行标题 display:block（本隐藏规则失效）共 9/9 帧；
       · 过渡目标高度 = 170px（含标题 28px + margin 16px），
         结束时加回 .collapse.show 变 125.2px ⇒ **44.8px 垂直跳变**；
       · 左右 padding 亦从 0px 跳到 8px。
     净效果 = 展开时先看到「带『项目:』、高 170px」的面板，随后被
     「无标题、高 125.2px」的白面板覆盖 = 用户反馈的现象。
     ⚠️ 桌面（≥768px）不隐藏标题（SB2 原样）⇒ 无「标题闪现」；但桌面仍有 **16px** 落差，
        来源 = SB2 原生 `.collapse-inner{margin:0 0 1rem 0}` 与 BS4 `.collapsing{overflow:hidden}`
        的交互（过渡期间 margin 计入 scrollHeight，收尾 overflow 恢复后 margin 溢出、不计入高度）。
        **改动前即存在、非本次引入**；桌面端维持 SB2 原样不动。
     实测（375px，全量 4 个一级菜单）：过渡期间首行可见帧 0/10、目标与最终落差 ≤0.2px、
     非首行 header（统计面板的「查询:」）零误藏。 */
  .sidebar .nav-item .collapse .collapse-inner,
  .sidebar .nav-item .collapsing .collapse-inner {
    box-shadow: none;
    border-radius: 0;
    margin-bottom: 0;
    padding: .25rem .5rem .5rem;
  }
  .sidebar .nav-item .collapse .collapse-inner .collapse-header,
  .sidebar .nav-item .collapsing .collapse-inner .collapse-header {
    padding: .4rem .75rem;
  }
  /* 面板顶行标题（「项目:」「统计:」「数据列表:」）**保留显示，不要隐藏**：
     2026-10-16 曾用 `.collapse-header:first-child { display:none }` 隐藏过（`f735cc4`，理由是
     「一级菜单已写明、标题同义冗余」），同日用户真机看过后拍板恢复 ⇒ 该规则已删除。
     ⚠️ 如再想隐藏，务必先读本段开头的 🔴🔴 —— 隐藏动作只挂 `.collapse` 会让它在 150ms
     过渡期内失效，直接导致「标题闪现 + 44.8px 高度跳变」两轮返工（`f735cc4`→`16116c5`）。 */
  .sidebar .nav-item .collapse .collapse-inner .collapse-item,
  .sidebar .nav-item .collapsing .collapse-inner .collapse-item {
    padding: var(--bb-sp-2) var(--bb-sp-3);
    border-radius: var(--bb-radius);
  }

  /* ⑩ SB2 的圆形折叠按钮在移动端无意义（抽屉由顶栏汉堡控制） */
  .sidebar #sidebarToggle {
    display: none !important;
  }

  /* ⑪ 顶栏：手机紧凑 + 吸顶（原 static-top 滚动后汉堡按钮会滚走） */
  .topbar.navbar {
    position: sticky !important;
    top: 0;
    z-index: 1030;
    margin-bottom: var(--bb-sp-4) !important;
    padding-left: var(--bb-sp-3);
    padding-right: var(--bb-sp-3);
  }
  #sidebarToggleTop {
    padding: .25rem .5rem;
    margin-right: var(--bb-sp-2) !important;
  }
  #sidebarToggleTop i {
    font-size: 1.25rem;
  }

  /* ⑫ 抽屉内关闭按钮 */
  .bb-drawer-close {
    position: absolute;
    top: var(--bb-sp-2);
    right: var(--bb-sp-2);
    z-index: 2;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .15);
    color: #fff;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
  }
  .bb-drawer-close:hover {
    background: rgba(255, 255, 255, .28);
  }
}

/* ============================================================
   四、桌面（>= 768px）：抽屉相关元素彻底不参与布局
   ============================================================ */
@media (min-width: 768px) {
  .bb-drawer-backdrop,
  .bb-drawer-close {
    display: none !important;
  }
}

/* ============================================================
   五、桌面侧栏宽度（2026-10-15）：14rem → 12rem
   ------------------------------------------------------------
   动机：一级菜单「标签左对齐 + 箭头贴右缘」，两者之间的空白只由
        「侧栏宽 − 标签长」决定。缩窄侧栏是压低这段空白最直接的手段，
        且完全不触碰左对齐栅格与刚校准好的箭头垂直对齐。

   取值依据（均为实测，非估算）：
     · 12rem = 192px 恰好让子菜单内层落在 SB Admin 2 自带的
       `.collapse-inner { min-width: 10rem }` 上（192 − 2×16 = 160px）
       ⇒ **12rem 是本项目可用的下限**，再窄子菜单（nowrap）就会被裁字。
     · 子菜单最长项「投资组合明细」墨迹 81.6px，右侧仍余 46.4px。
     · 版心 1216px → 1248px（+32px），所有页面可用宽同增。

   ⚠️ nav-link 的宽度必须跟着改：SB Admin 2 把 `.sidebar .nav-item .nav-link`
      写死 14rem（sb-admin-2.min.css）。若不覆盖，在 192px 的侧栏里它仍是
      224px，箭头（right:1rem，相对 nav-link 定位）会被推到 x=201.6 ——
      溢出侧栏、压在版心上（实测）。
   ⚠️ 必须用 `:not(.toggled)` 限定：`.sidebar.toggled .nav-item .nav-link
      { width: 6.5rem }` 与本规则同为 3 个 class 优先级，只靠先后顺序分胜负；
      加 :not(.toggled) 后两者互不冲突，折叠态保持 SB Admin 2 原样。
   ⚠️ 品牌区必须同时收窄：`.sidebar-brand-text`「资产管理系统」6 字在实际
      步进 16.8px/字下需 100.8px，加图标 40.5px 与 mx-3 的 32px 共 173.3px，
      而 12rem 的品牌内容盒只有 160px ⇒ 折行（实测文字盒高 24 → 48px，
      品牌区固定 4.375rem 会被撑破）。内边距 1rem→.75rem 且 mx-3→.5rem 后
      实际余量 22.5px（图标左缘 17.3、文字右缘 162.8，均落在 168px 内容盒内）。
      mx-3 是 Bootstrap 工具类、自带 !important，覆盖时必须同样 !important。
   ------------------------------------------------------------ */
@media (min-width: 768px) {
  .sidebar {
    width: var(--bb-sidebar-w) !important;   /* 12rem = 192px */
  }
  .sidebar:not(.toggled) .nav-item .nav-link {
    width: var(--bb-sidebar-w);              /* 不覆盖则仍为 14rem，箭头溢出 */
  }
  /* 品牌区收窄：补偿侧栏变窄，避免标题折行 */
  .sidebar .sidebar-brand {
    padding-left: .75rem;
    padding-right: .75rem;
  }
  .sidebar .sidebar-brand .sidebar-brand-text {
    margin-left: .5rem !important;           /* 覆盖 BS4 .mx-3（带 !important） */
    margin-right: .5rem !important;
  }
}

/* ============================================================
   六、宽表滑动提示（P2-2a · 2026-10-15，仅移动端 <768px）
   ------------------------------------------------------------
   背景：真机反馈「近期交易/近期分红/近期打新/持仓股票一览在手机端都
        有横向滚动」。.table-responsive 在 BS4 里是 overflow-x:auto，
        手机上确实要横着拖，但**没有任何视觉暗示**，用户不知道右边还有列。
   做法：skeleton.js 检测到 table.scrollWidth > 容器 clientWidth 时给
        容器加 .bb-is-scrollable（右缘渐隐阴影）并在其后插入一行提示。
        ⚠️ 仅 <768px：桌面三张近期*表本就小幅溢出（43/35/93px，既有
        状况、被认可的基线），提示不该出现在桌面。
   为什么用 inset box-shadow 而不是 ::after 渐变：滚动容器内的绝对定位
        伪元素是随内容滚动的（right:0 会停在内容末端而不是可视右缘），
        而 inset 阴影画在元素自身的可视盒上，不随滚动移动。
   ============================================================ */
.bb-is-scrollable {
  box-shadow: inset -16px 0 12px -10px rgba(58, 59, 69, .22);
}
.bb-scroll-hint {
  font-size: .75rem;
  color: #9ca3af;
  text-align: center;
  padding-top: 2px;
  user-select: none;
}
