/* ==========================================================================
 *  宜宇 · 原生手势层样式（gesture.css）2026-09-20
 *  --------------------------------------------------------------------------
 *  与 gesture.js 配对，两端共用（PHP layout.php / Nuxt nuxt.config.ts head.link）。
 *  这里只放「手势产生的视觉」，不改任何既有组件的外观。
 *
 *  ★ 为什么把 touch-action / overscroll-behavior 放在这里
 *    浏览器自己也要处理横向滑动（历史前进后退）和下拉（Chrome 安卓自带
 *    下拉刷新）。不显式声明，用户会同时触发「我们的手势」和「浏览器的」，
 *    表现就是页面抽搐。所以：
 *      · html,body 声明 touch-action: pan-y —— 横向交给 JS 独占；
 *      · html,body 声明 overscroll-behavior-y: contain —— 压掉浏览器自带
 *        下拉刷新，避让我们的 #yqPtr。
 *    局部若确实需要原生横向滚动，给那个容器单独写 touch-action: pan-x
 *    （或加 .yq-hscroll），gesture.js 会整条放行。
 * ========================================================================== */

html[data-yq-gesture] body {
  touch-action: pan-y;
  overscroll-behavior-y: contain;
}

/* 惯性滚动：iOS 的老写法在 16+ 已默认开启，但安卓部分定制内核仍需它 */
.yq-main,
.yq-hscroll,
.yq-water,
.pr-list,
.ct-list,
.wf-list {
  -webkit-overflow-scrolling: touch;
}

/* 手势进行中：给整个 App 提一层阴影，制造「页面被推走」的纵深 */
.yq-app.is-swiping-back {
  box-shadow: -8px 0 26px rgba(0, 0, 0, .22);
  will-change: transform;
}

/* ==========================================================================
 *  ③ 下拉刷新指示器
 * ========================================================================== */
.yq-ptr {
  position: fixed;
  left: 50%;
  top: 0;
  z-index: 150;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border-radius: var(--r-full, 999px);
  background: var(--bg-raise, #fff);
  color: var(--text-second, #5d6b63);
  font-size: .78rem;
  line-height: 1;
  box-shadow: var(--sh-2, 0 2px 10px rgba(0, 0, 0, .08));
  border: 1px solid var(--line, #e6efe9);
  transform: translate3d(-50%, -56px, 0);
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s var(--ease-out, ease);
  will-change: transform, opacity;
}
.yq-ptr.is-on { opacity: 1; }
.yq-ptr.is-ready { color: var(--brand-600, #12a054); border-color: var(--brand-200, #aef0c8); }
.yq-ptr__spin {
  width: 13px; height: 13px;
  border-radius: 50%;
  border: 2px solid var(--line-strong, #dbe9e0);
  border-top-color: var(--brand-500, #1fbe66);
  flex: 0 0 auto;
}
.yq-ptr.is-busy .yq-ptr__spin { animation: yq-ptr-spin .7s linear infinite; }
@keyframes yq-ptr-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .yq-ptr { transition: none; }
}

/* ==========================================================================
 *  ④ 长按上下文菜单（底部动作面板）
 * ========================================================================== */
.yq-ctx { position: fixed; inset: 0; z-index: 300; }
.yq-ctx[hidden] { display: none; }
.yq-ctx__mask {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; padding: 0;
  background: rgba(12, 18, 14, .42);
  opacity: 0;
  transition: opacity .18s var(--ease-out, ease);
}
.yq-ctx.is-on .yq-ctx__mask { opacity: 1; }
.yq-ctx__panel {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  margin: 0 auto;
  max-width: 520px;
  padding: 8px 10px calc(10px + var(--safe-bot, 0px));
  background: var(--bg-raise, #fff);
  border-radius: var(--r-lg, 20px) var(--r-lg, 20px) 0 0;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, .18);
  transform: translate3d(0, 100%, 0);
  transition: transform .22s cubic-bezier(.22,.61,.36,1);
}
.yq-ctx.is-on .yq-ctx__panel { transform: translate3d(0, 0, 0); }
.yq-ctx__hd {
  padding: 9px 8px 10px;
  font-size: .78rem;
  color: var(--text-third, #93a29a);
  text-align: center;
  border-bottom: 1px solid var(--line, #e6efe9);
}
.yq-ctx__hd:empty { display: none; }
.yq-ctx__acts { padding: 4px 0; }
.yq-ctx__a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 50px;                 /* 适老 / 好点 */
  padding: 0 12px;
  border: 0;
  background: none;
  border-radius: var(--r-sm, 10px);
  font-size: .94rem;
  font-family: inherit;
  color: var(--text-primary, #17211b);
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.yq-ctx__a:active { background: var(--bg-sunken, #eaf3ed); }
.yq-ctx__a.is-danger { color: #c0392b; }
.yq-ctx__a + .yq-ctx__a { border-top: 1px solid var(--line, #e6efe9); }
.yq-ctx__cancel {
  display: block;
  width: 100%;
  min-height: 50px;
  margin-top: 6px;
  border: 0;
  border-radius: var(--r-sm, 10px);
  background: var(--bg-sunken, #eaf3ed);
  color: var(--text-second, #5d6b63);
  font-size: .94rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
}

/* ==========================================================================
 *  ⑤ 双击爱心
 * ========================================================================== */
.yq-dblheart {
  position: fixed;
  z-index: 250;
  color: #ff2e4d;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(.35);
  opacity: 0;
  animation: yq-dblheart .7s var(--ease-out, cubic-bezier(.22,.61,.36,1)) forwards;
  filter: drop-shadow(0 2px 10px rgba(255, 46, 77, .35));
}
@keyframes yq-dblheart {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.35) rotate(-12deg); }
  32%  { opacity: .96; transform: translate(-50%, -50%) scale(1.16) rotate(6deg); }
  58%  { opacity: .96; transform: translate(-50%, -50%) scale(.98) rotate(0deg); }
  100% { opacity: 0; transform: translate(-50%, -128%) scale(.82); }
}
@media (prefers-reduced-motion: reduce) {
  .yq-dblheart { animation-duration: .35s; }
}

/* ==========================================================================
 *  ⑥ 列表项左滑露出操作
 *  用法（两端模板同构）：
 *    <li class="yq-sw" data-swipe>
 *      <div class="yq-sw__row">…正常内容…</div>
 *      <div class="yq-sw__acts" data-swipe-acts>
 *        <button class="yq-sw__a" type="button">标记已读</button>
 *        <button class="yq-sw__a is-danger" type="button">删除</button>
 *      </div>
 *    </li>
 *  注意：data-swipe 挂在**外层**，transform 也加在外层 —— 这样内层
 *  自己的点击/长按逻辑完全不受影响。
 * ========================================================================== */
[data-swipe] {
  position: relative;
  touch-action: pan-y;
  will-change: transform;
  background: transparent;
}
.yq-sw__acts {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  display: flex;
  align-items: stretch;
  z-index: 0;
}
.yq-sw__row {
  position: relative;
  z-index: 1;
  background: var(--bg-raise, #fff);
}
.yq-sw__a {
  width: 84px;
  border: 0;
  background: var(--bg-sunken, #eaf3ed);
  color: var(--text-primary, #17211b);
  font-size: .82rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.yq-sw__a.is-danger { background: #fdeceb; color: #c0392b; }
.yq-sw__a:active { filter: brightness(.95); }

html[data-theme="dark"] .yq-sw__a { background: #1b211e; color: #eef2ef; }
html[data-theme="dark"] .yq-sw__a.is-danger { background: #33201f; color: #ff8a80; }

/* ==========================================================================
 *  原生壳（Capacitor / WebView 容器）下的补充修正
 *  --------------------------------------------------------------------------
 *  壳里没有浏览器 chrome，安全区由原生注入的 CSS 变量给；
 *  同时把「下载 App」这类入口藏掉（壳里点它会很荒谬）。
 * ========================================================================== */
html.yq-native .yq-dl-entry,
html.yq-native [data-hide-in-native] { display: none !important; }

/* Bug B 修复（2026-09-20）：App 内顶部安全区已由原生 WebView margin 承担
   （MainActivity.applyWebViewInsets 把状态栏高度加成 topMargin）。
   这里若再补 padding-top 就是双倍 —— 表现为页面顶部（尤其下拉刷新后）
   多出一条状态栏高度的空白。因此原生模式下 body 顶部必须为 0。 */

/* 2026-09-21 兜底加强（消息页顶部 ~150px 空白的根治）：
   旧版 App（≤1.9.0）运行时注入的 yq-native.js 还带着
     html.yq-native body { padding-top: var(--safe-top) !important }
   而 --safe-top 映射的 --yq-inset-top 是原生给的「设备像素」值
   （含刘海的手机上 100-150px），浏览器把它当 CSS 像素渲染，
   再叠加 v4 原生 margin 就是双重补边 —— 消息页内容短，最显眼。
   这里用更高特异性（body.yq-body / body:last-child）+ !important 压过它；
   新版 App（≥1.9.1）已不再注入 body padding，本规则无副作用。 */
html.yq-native body.yq-body,
html.yq-native body:last-child {
  padding-top: 0 !important;
}
