/* 索引云 · 小程序中心启动器
   顶栏的汉堡按钮 → 左侧滑出抽屉 → 点开小程序后以浮动窗口盖在主界面上。
   样式全部用 wb- 前缀，页面本身不用写任何 DOM。 */

/* ============================ 顶栏按钮 ============================ */
.wb-launch-btn {
  width: 34px; height: 34px;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  transition: background var(--dur-2) var(--ease),
              border-color var(--dur-2) var(--ease),
              transform var(--dur-1) var(--ease);
}
.wb-launch-btn span {
  display: block;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  background: var(--text-3);
  transition: background var(--dur-2) var(--ease), width var(--dur-2) var(--ease);
}
.wb-launch-btn:hover { background: var(--surface-2); border-color: var(--line); }
.wb-launch-btn:hover span { background: var(--text); }
.wb-launch-btn:active { transform: scale(.92); }
.wb-launch-btn.on { background: var(--brand-soft); border-color: var(--brand); }
.wb-launch-btn.on span { background: var(--brand); }
/* 打开时三条线收成一条更短的（"已展开"的暗示） */
.wb-launch-btn.on span:nth-child(1) { width: 11px; }
.wb-launch-btn.on span:nth-child(3) { width: 11px; }

/* ============================ 抽屉 ============================
   ⚠️ 层级说明见 style.css 的「层级总表」。抽屉必须用 --z-mask / --z-drawer，
   不能用写死的 400/410 —— 浮窗开着时底下页面会被抬到 1100 以上，
   写死的数字会被反超，出现「抽屉的字跑到浮窗上面」那个 bug。 */
.wb-drawer-mask {
  position: fixed; inset: 0; z-index: var(--z-mask, 1240);
  background: rgba(20, 25, 33, .26);
  backdrop-filter: blur(1px);
  -webkit-backdrop-filter: blur(1px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-2) var(--ease);
}
.wb-drawer-mask.open { opacity: 1; pointer-events: auto; }

.wb-drawer {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: var(--z-drawer, 1250);
  width: 25vw; min-width: 268px; max-width: 360px;
  background: var(--surface);
  border-right: 1px solid var(--line);
  box-shadow: 6px 0 28px rgba(0, 0, 0, .10);
  transform: translateX(-101%);
  transition: transform var(--dur-3) var(--ease-out);
  display: flex; flex-direction: column;
  will-change: transform;
}
.wb-drawer.open { transform: translateX(0); }

.wb-drawer-head {
  height: 56px; flex-shrink: 0;
  display: flex; align-items: center; gap: 10px;
  padding: 0 10px 0 20px;
  border-bottom: 1px solid var(--line);
}
.wb-drawer-title { font-size: 15px; font-weight: 600; }
.wb-drawer-body { flex: 1; overflow-y: auto; padding: 12px; }

.wb-app-item {
  display: flex; align-items: center; gap: 13px;
  width: 100%;
  padding: 13px 14px;
  margin-bottom: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  box-shadow: var(--sh-1);
  transition: border-color var(--dur-2) var(--ease),
              background var(--dur-2) var(--ease),
              box-shadow var(--dur-2) var(--ease),
              transform var(--dur-1) var(--ease);
}
.wb-app-item:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
  box-shadow: var(--sh-2);
  transform: translateX(2px);
}
.wb-app-item:active { transform: translateX(2px) scale(.985); }
.wb-app-item .ico {
  width: 36px; height: 36px; flex-shrink: 0;
  border-radius: 10px;
  background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
  font-size: 19px;
  transition: background var(--dur-2) var(--ease),
              transform var(--dur-3) var(--spring);
}
.wb-app-item:hover .ico { background: #fff; transform: scale(1.08) rotate(-3deg); }
.wb-app-item .nm { font-size: 14px; font-weight: 600; }
.wb-app-item .ds { font-size: 12px; color: var(--text-3); line-height: 1.45; margin-top: 2px; }

.wb-drawer-foot {
  flex-shrink: 0;
  padding: 12px 20px 16px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.7;
}

/* ============================ 通用小图标按钮 ============================ */
.wb-icon-btn {
  width: 32px; height: 32px;
  flex-shrink: 0;
  border: none; border-radius: 8px;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--dur-2) var(--ease),
              color var(--dur-2) var(--ease),
              transform var(--dur-1) var(--ease);
}
.wb-icon-btn:hover { background: var(--surface-2); color: var(--text); }
.wb-icon-btn:active { transform: scale(.9); }
.wb-icon-btn svg { display: block; }

/* ============================ 浮动窗口 ============================
   浮窗是「真·浮动」：只挡住它自己那一块，后面的页面照常能看能用。
   所以这里没有全屏遮罩，也没有滚动锁。
   ⚠️ 层级用 --z-win（见 style.css 总表），必须比抽屉、设置浮窗、抬高的顶栏都高。 */
.wb-win-layer {
  position: fixed; inset: 0; z-index: var(--z-win, 1300);
  display: none;
  /* 关键：这一层只有窗口本身是可点的，其余区域鼠标事件全部穿透到下面去 */
  pointer-events: none;
}
.wb-win-layer.open { display: block; }

/* 最大化时：浮窗铺满整屏，标题栏正好压在页面顶栏那个位置。
   顶栏(1320) 平时是压在浮窗(1300) 上面的（为了让后面那层还能点），
   但最大化时会把窗口自己的「还原 / 退出」按钮盖住 —— 用户放大后就还原不回来了。
   所以最大化时抬到 --z-win-max(1400)，保证标题栏按钮永远点得到。
   （非最大化时顶栏仍在上，后面那层照常能用。） */
body.wb-win-max .wb-win-layer { z-index: var(--z-win-max, 1400); }

/* ⚠️ 上面这一抬，会把抽屉(1340)和它的遮罩(1330)反超 ——
   「抽屉永远在浮窗之上」这条约定在最大化时就断了（抽屉会藏在浮窗后面点不到）。
   所以最大化时抽屉和遮罩要跟着抬，还是保持「遮罩 < 抽屉」且两者都 > 浮窗 这个相对关系。
   （+1/+2 而不是直接顶到 1400：同层数时按 DOM 顺序画，浮窗层在后面就会反过来压住遮罩，
     那就跟非最大化时的观感不一样了。）
   抽屉在最大化时本来就不太够得着（顶栏被浮窗盖住了），但这条约定不能有例外 ——
   免得以后哪条路径又把抽屉打开时，发现它被压在底下。 */
body.wb-win-max .wb-drawer-mask { z-index: calc(var(--z-win-max, 1400) + 1); }
body.wb-win-max .wb-drawer { z-index: calc(var(--z-win-max, 1400) + 2); }

/* 窗口用 left/top/width/height 定位（不再用 transform 居中），
   这样拖拽移动、四边拉伸才准确。 */
.wb-win {
  position: absolute;
  left: 0; top: 0;
  width: min(1000px, 92vw);
  height: min(740px, 87vh);
  background: var(--surface);
  border-radius: var(--radius);
  /* 浮窗不铺遮罩，靠这圈阴影把层次拉开：外面一圈柔和的投影 +
     一圈淡淡的描边，让窗口看起来是「浮」在页面上的 */
  box-shadow: 0 18px 50px rgba(0, 0, 0, .20),
              0 3px 12px rgba(0, 0, 0, .10),
              0 0 0 1px rgba(0, 0, 0, .06);
  display: flex; flex-direction: column;
  overflow: hidden;
  will-change: left, top, width, height;
  /* 浮窗自己是可点的（父层 pointer-events:none 在这里收回） */
  pointer-events: auto;
}
/* 最大化 / 还原、拖动结束归位这类需要动画的时刻才加 .anim */
.wb-win.anim {
  transition: left .2s var(--ease-out),
              top .2s var(--ease-out),
              width .2s var(--ease-out),
              height .2s var(--ease-out),
              border-radius .2s var(--ease);
}
.wb-win.max {
  left: 0 !important; top: 0 !important;
  /* ⚠️ 必须是 100vw/100vh（`width:100%` 反而不行）：这里量的是**视口**宽，
     而宽度基准是"初始包含块"（含右侧滚动条那一条），`100vw` 正好等于它。
     改成 `100%` 会拿到内容区宽（短一个滚动条），最大化完右边留一条缝。 */
  width: 100vw !important;
  height: 100vh !important;
  border-radius: 0;
}
/* 最大化时不给拖拽 / 拉伸的提示 */
.wb-win.max .wb-win-bar { cursor: default; }
.wb-win.max .wb-resize { display: none; }
@keyframes wbWinIn {
  from { opacity: 0; transform: scale(.965) translateY(8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.wb-win.animate { animation: wbWinIn .26s var(--ease-out); }

/* 拖动中 / 拉伸中：整个页面强制成对应光标，避免光标乱跳 */
body.wb-dragging,
body.wb-dragging * { cursor: grabbing !important; }
body.wb-resizing,
body.wb-resizing * { cursor: inherit !important; }
body.wb-dragging iframe,
body.wb-resizing iframe { pointer-events: none !important; }

.wb-win-bar {
  height: 46px; flex-shrink: 0;
  display: flex; align-items: center; gap: 8px;
  padding: 0 8px 0 10px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
  touch-action: none;
}
.wb-win-bar.grabbing { cursor: grabbing; }
.wb-win-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 600;
  min-width: 0;
  pointer-events: none;   /* 标题不参与拖拽判定，简化逻辑 */
}
.wb-win-drag-hint {
  font-size: 12px; color: var(--text-3);
  margin-left: 6px;
  pointer-events: none;
  opacity: .8;
}

/* ---------- 八方向的放大缩小把手 ---------- */
.wb-resize {
  position: absolute;
  z-index: 3;
  touch-action: none;
}
.wb-resize.n  { top: -3px; left: 12px; right: 12px; height: 8px; cursor: ns-resize; }
.wb-resize.s  { bottom: -3px; left: 12px; right: 12px; height: 8px; cursor: ns-resize; }
.wb-resize.w  { left: -3px; top: 12px; bottom: 12px; width: 8px; cursor: ew-resize; }
.wb-resize.e  { right: -3px; top: 12px; bottom: 12px; width: 8px; cursor: ew-resize; }
.wb-resize.nw { left: -3px; top: -3px; width: 16px; height: 16px; cursor: nwse-resize; }
.wb-resize.ne { right: -3px; top: -3px; width: 16px; height: 16px; cursor: nesw-resize; }
.wb-resize.sw { left: -3px; bottom: -3px; width: 16px; height: 16px; cursor: nesw-resize; }
.wb-resize.se { right: -3px; bottom: -3px; width: 16px; height: 16px; cursor: nwse-resize; }
/* 右下角画两条短线，提示这里能拉 */
.wb-resize.se::after {
  content: '';
  position: absolute;
  right: 4px; bottom: 4px;
  width: 9px; height: 9px;
  border-right: 1.6px solid var(--text-3);
  border-bottom: 1.6px solid var(--text-3);
  border-radius: 0 0 3px 0;
  opacity: .55;
}
.wb-win-title .ic { font-size: 16px; }
.wb-win-title .tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wb-win-actions { margin-left: auto; display: flex; gap: 2px; flex-shrink: 0; }
.wb-win-btn {
  height: 32px;
  border: none; border-radius: 8px;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  padding: 0 9px;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 13px;
  font-family: inherit;
  white-space: nowrap;
  transition: background var(--dur-2) var(--ease),
              color var(--dur-2) var(--ease),
              transform var(--dur-1) var(--ease);
}
.wb-win-btn:hover { background: var(--line); color: var(--text); }
.wb-win-btn:active { transform: scale(.94); }
.wb-win-btn.close:hover { background: var(--bad); color: #fff; }
.wb-win-btn svg { display: block; }

.wb-win-body { flex: 1; min-height: 0; position: relative; background: var(--bg); }
.wb-win-body iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: none;
  display: block;
}

/* 浮窗打开时：不再锁滚动，后面的页面照常能滚能点。
   body.wb-locked 只用来做个标记（脚本和测试会看），不带样式。 */

/* ---------- 让浮窗打开时，底下的顶栏仍然能点（不被浮窗盖住） ----------
   思路：浮窗开着时，把「顶栏」抬到浮窗之上（--z-topbar），这样窗口压住顶栏那一截时，
   那一截点到的仍然是顶栏按钮，用户还能去开抽屉 / 设置 / 学英语。
   ⚠️ 内容区（.wrap/.container/main）抬到 --z-page-nav 这一档：
      要比顶栏低，也要比「抽屉、设置浮窗」低 —— 之前就是把它抬到 1100，
      又比抽屉(410) 高，才出现「抽屉被页面盖住 / 字跑到框上面」那个 bug。
      现在统一用总表里的变量，抽屉(1340) > 页面(1180)，不会再打架。
   ⚠️ 这里**只改 z-index**，position 必须保持和 style.css 一致（fixed）——
      顶栏现在是「浮动 + 自动收起」的，一旦在这儿把它改回 sticky，
      收起时就不再脱出文档流，上方会白白留下一条 56px 的空白。
   ⚠️ 改完务必确认注释是闭合的：上面这段注释如果漏掉闭合标记，
      紧跟其后的这条规则会被 CSS 解析器当成垃圾一起吞掉，
      表现就是「浮窗一开，顶栏被页面盖住、点不着」。（踩过，跑 css-syntax.js 能查） */
body.wb-win-open .topbar { z-index: var(--z-topbar, 1320); }
body.wb-win-open main,
body.wb-win-open .wrap,
body.wb-win-open .container { position: relative; z-index: var(--z-page-nav, 1180); }

@media (max-width: 720px) {
  .wb-drawer { width: 82vw; max-width: none; }
  .wb-win-btn .lbl { display: none; }
  .wb-win-btn { padding: 0 8px; }
  .wb-win-drag-hint { display: none; }
}

/* ============================ 整屏覆盖层 ============================
   ⚠️ 它要盖住**所有**东西（顶栏、抽屉、浮窗、设置浮窗），只留一个"退出"。
      所以层级用 --z-cover(1900)，比设置浮窗(1450) 高，
      但故意比成就提示条(2000) 低 —— 被盖住的页面里拿到成就，提示照样能飘出来。
   ⚠️ 现在**没有小程序用它**了（唯一的用户「幻想岛」2026-09-28 已归档）。
      整套机制留着没拆：它跟浮窗那套在焦点转发 / Esc / 层级上纠缠，
      拆掉的动静比留着大。以后要做"一进去整屏跑"的东西，APPS 里加 `cover: true` 就行。 */
.wb-cover-layer {
  position: fixed; inset: 0;
  z-index: var(--z-cover, 1900);
  display: none;
  background: #0b1020;
}
.wb-cover-layer.open { display: block; }
.wb-cover-frame {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
  display: block;
}
/* 退出按钮：浮在右上角。用半透明深色，在亮天和暗夜里都看得清。 */
.wb-cover-exit {
  position: absolute;
  top: 14px; right: 14px;
  z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  background: rgba(12, 16, 28, .52);
  border: 1px solid rgba(255, 255, 255, .28);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease), transform var(--dur-1) var(--ease);
}
.wb-cover-exit:hover { background: rgba(12, 16, 28, .78); }
.wb-cover-exit:active { transform: scale(.95); }
.wb-cover-exit svg { width: 13px; height: 13px; }

/* 覆盖开着的时候，别让后面的页面还能滚（不然滚轮会滚到底下那层） */
body.wb-cover-open { overflow: hidden; }

/* 夜间模式期间藏掉浮窗标题栏（2026-10-18 用户要求）——
   只剩内容，像一块真正的幕布；退出夜间模式自动恢复。 */
.wb-win.night-bar-off .wb-win-bar { display: none !important; }
