/* =========================================================================
   mobile.css —— 移动端统一覆盖层
   -------------------------------------------------------------------------
   为什么单独一个文件：
   style.css（index.html 用）与 css/styles.css（tojav.html 用）是两份高度重复的
   92KB / 125KB 单体样式，历史上已经出现过漂移（同一断点下 .modal-close 一个是
   44px、一个是 34px）。移动端改动若分别写进两份文件，必然再次漂移。
   因此把「移动端增量」集中在本文件，由两个页面在各自的主样式 *之后* 引入，
   同特异性下后者覆盖前者 —— 桌面（> 各断点）完全不受影响。

   统一断点（单一来源，两个页面与 JS 共用同一套语义）：
     1024 —— 平板横屏 / 小笔电（hero、Hero 轮播、搜索框收起）
      768 —— 主断点：手机横竖屏分界，绝大部分移动端改造在此
      480 —— 超窄屏（≤414 的 iPhone SE / 老安卓）
   ========================================================================= */

/* ============ A. 全局兜底（与视口无关，所有设备生效） ============ */

/* A1 禁止 iOS 横屏时自动放大字号导致的布局错乱（配合下面 16px 输入框） */
html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* A2 兜住任何意外的横向溢出。
   注意用 overflow-x: clip 而不是 hidden —— hidden 会让元素成为滚动容器，
   从而破坏内部 position: sticky（弹窗头部是 sticky 的）；不支持 clip 的
   老浏览器回退到 hidden，只是少一点点 sticky 能力，不会错版。 */
html {
    overflow-x: hidden;
}

body {
    overflow-x: hidden;
}

@supports (overflow: clip) {

    html,
    body {
        overflow-x: clip;
    }
}

/* A3 去掉移动端常见的 300ms 点击延迟 / 双击缩放歧义 */
a,
button,
input,
select,
textarea,
label,
[role="button"] {
    touch-action: manipulation;
}

/* A4 键盘可达性（移动端外接键盘 / 无障碍）——焦点环跟随「放映暖光」琥珀 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid #ffb938;
    outline-offset: 2px;
}

/* A5 所有自带滚动的抽屉 / 弹层禁止滚动链穿透（滚到顶带着 body 一起动） */
.sidebar-nav,
.mobile-nav,
.admin-container,
.search-popup-panel,
.modal-thumb-strip,
.table-container {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}


/* ============ B. 输入框统一 16px —— 消除 iOS 聚焦自动缩放 ============ */
/* iOS Safari 对 font-size < 16px 的表单控件会在聚焦瞬间整页放大且不自动还原。
   这里按「窄屏 + 触屏」两个条件命中所有出现过的输入框。 */
@media (max-width: 1024px),
(hover: none) and (pointer: coarse) {

    input:not([type="button"]):not([type="submit"]):not([type="reset"]),
    select,
    textarea {
        font-size: 16px;
    }

    /* 页码跳转框和管理面板的「新增用户」原为 0.9rem（≈14.4px），是主要踩坑点 */
    .page-input,
    .admin-add-form input,
    .header-search-input,
    .search-input,
    .search-form-popup input,
    .login-form-group input {
        font-size: 16px;
    }
}


/* ============ C. ≤1024px：平板 / 小屏笔电 ============ */
@media (max-width: 1024px) {
    .hero {
        height: 55vh;
        height: 55dvh;
    }
}


/* ============ D. ≤768px：主移动端断点 ============ */
/* 头部左侧登录按钮（原 ☰ 菜单按钮位置）：桌面端不显示，仅 ≤768 启用 */
.mobile-login-btn {
    display: none;
}

/* 移动端自包含下拉（含「登出」）：桌面端不显示，仅 ≤768 启用，
   显隐由 .open 控制（见下方媒体查询）。基础态必须隐藏，否则桌面会露出登出。 */
.mobile-user-menu {
    display: none;
}

@media (max-width: 768px) {

    /* ---------- D1 视口高度塌陷：vh → dvh ----------
       移动浏览器的地址栏会伸缩，100vh 按「地址栏收起」的大视口计算，
       于是抽屉底部的登录/登出按钮会被浏览器工具栏压住。
       先写 vh 再写 dvh：不支持 dvh 的浏览器自动回退到第一行。 */
    body {
        min-height: 100vh;
        min-height: 100dvh;
    }

    .sidebar-nav {
        height: 100vh;
        height: 100dvh;
    }

    .mobile-nav {
        height: 100vh;
        height: 100dvh;
    }

    .search-popup-panel,
    .admin-container,
    .hero-picker-dialog {
        max-height: 85vh;
        max-height: 85dvh;
    }

    .modal-content {
        max-height: 65vh;
        max-height: 65dvh;
    }

    .modal-stack {
        height: 70vh;
        height: 70dvh;
    }

    .hero {
        height: 45vh;
        height: 45dvh;
        min-height: 280px;
    }

    /* 表格卡片化后不再需要撑高的占位高度 */
    .table-container {
        min-height: 0;
    }


    /* ---------- D2 表格视图 → 卡片堆叠 ----------
       桌面是 8 列 table-layout: fixed；390px 下每列只有约 48px，
       表头还有 white-space: nowrap，内容互相重叠无法阅读。
       这里在移动端把行拆成「一张卡片一行字段」的两列式布局，
       字段标题用 ::before 生成（各 td 有稳定的 .td-* 类名，无需改模板）。 */
    .table-container {
        padding: 0 8px;
        overflow-x: visible;
        /* contain: layout style 会约束内部布局，卡片化后不再需要 */
        contain: none;
    }

    .data-table {
        display: block;
        width: 100%;
        background: transparent;
        border-radius: 0;
        overflow: visible;
    }

    .data-table thead {
        display: none;
    }

    .data-table tbody {
        display: block;
    }

    .data-table tbody tr {
        display: block;
        margin: 0 0 10px;
        padding: 10px 12px;
        background: rgba(30, 30, 50, 0.6);
        border: 1px solid rgba(255, 255, 255, 0.08);
        border-radius: 12px;
    }

    .data-table tbody tr:hover {
        background: rgba(102, 126, 234, 0.1);
    }

    /* 列出 1~8 是为了压过原有 .data-table td:nth-child(n) 的百分比宽度
       （同特异性，靠本文件加载在后来胜出） */
    .data-table td:nth-child(1),
    .data-table td:nth-child(2),
    .data-table td:nth-child(3),
    .data-table td:nth-child(4),
    .data-table td:nth-child(5),
    .data-table td:nth-child(6),
    .data-table td:nth-child(7),
    .data-table td:nth-child(8) {
        display: flex;
        align-items: center;
        gap: 10px;
        box-sizing: border-box;
        width: 100%;
        max-width: none;
        min-width: 0;
        padding: 7px 0;
        border-bottom: 1px dashed rgba(255, 255, 255, 0.07);
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        font-size: 0.85rem;
        line-height: 1.5;
    }

    .data-table tbody tr td:last-child {
        border-bottom: 0;
    }

    /* 空字段（没有来源 / 没有种子名）直接不占位 */
    .data-table td:empty {
        display: none;
    }

    .data-table td::before {
        flex: 0 0 60px;
        color: #a5b4fc;
        font-size: 0.75rem;
        font-weight: 600;
        letter-spacing: 0.04em;
    }

    .td-source::before {
        content: '来源';
    }

    .td-title::before {
        content: '名称';
    }

    .td-format::before {
        content: '格式';
    }

    .td-size::before {
        content: '大小';
    }

    .td-coded::before {
        content: '类型';
    }

    .td-seed::before {
        content: '种子';
    }

    .td-time::before {
        content: '时间';
    }

    .td-magnet::before {
        content: '链接';
    }

    /* 标题允许换行而不是截断；登录锁定占位同理 */
    .data-table .title-link,
    .data-table .table-data-locked {
        flex: 1 1 auto;
        min-width: 0;
        overflow-wrap: anywhere;
        white-space: normal;
        font-size: 0.85rem;
        line-height: 1.5;
    }

    /* 表格来源徽章 / 磁力按钮的移动端尺寸已并入 tags.css（统一标签组件） */


    /* ---------- D3 触控目标：统一补到 ≥44px ----------
       style.css 的 768 块已经处理了一批（分页、抽屉项、右侧悬浮面板），
       这里补齐剩下几处遗漏、以及被 styles.css 在窄屏反向缩小的地方。 */

    /* 图片弹窗关闭按钮：styles.css 在 768 断点把它缩到 34px，这里拉回 44px，
       与另一份 style.css 的取值保持一致 */
    .modal-close {
        width: 44px;
        height: 44px;
        font-size: 1.25rem;
        top: calc(12px + env(safe-area-inset-top, 0px));
        right: calc(12px + env(safe-area-inset-right, 0px));
    }

    .modal-thumb-item {
        width: 48px;
        height: 36px;
    }

    /* tojav 头部：放大镜按钮原 30×30，≤768px 时它是展开搜索的唯一入口 */
    .header-actions .search-box button,
    .header-actions .header-search-btn {
        width: 44px;
        height: 44px;
        box-sizing: border-box;
    }

    /* 放大镜按钮：去掉 styles.css 给的圆形底（rgba(102,126,234,.25) + 同色边框）。
       ≤768px 下它只是进入全屏搜索层的入口，不需要靠一圈底色表明“可点”，
       44×44 的触控面积仍在（上面那条规则），去掉后头部更干净。 */
    .header-actions .search-box button {
        background: transparent;
        border-color: transparent;
    }

    /* 图标从 14×14 放大到 22×22，与 ☰ 菜单按钮里三条横杠的 svg 尺寸一致
       —— 两个按钮在 header 里并排，图标一大一小会很扎眼。 */
    .header-actions .search-box button svg {
        width: 22px;
        height: 22px;
    }

    /* 悬停同样对齐 ☰：菜单按钮的 hover 只是「变白 + 底色微亮」，没有紫色高亮、
       没有发光、图标也不转（styles.css 里给放大镜的是紫底 + box-shadow +
       rotate(-15deg) scale(1.1)，两个按钮并排时反馈形式完全不一样）。
       放大镜已经没有底色了，所以这里只把图标提亮，保持无底、无位移。 */
    .header-actions .search-box button:hover {
        background: transparent;
        border-color: transparent;
        color: #fff;
        box-shadow: none;
    }

    .header-actions .search-box button:hover svg,
    .header-actions .search-box button:active svg {
        transform: none;
    }

    /* ☰ 菜单按钮、回到顶部 */
    .mobile-menu-btn,
    .back-to-top {
        min-width: 44px;
        min-height: 44px;
        box-sizing: border-box;
    }

    /* ☰ 只要图标，不要「菜单」二字：按钮上已有 aria-label="打开菜单"，文字是
       冗余的，而且它和放大镜并排时会把 header 挤得更满。
       styles.css 只在 ≤480 隐藏这个 label，481~768 这段仍会露出来，所以这里在
       ≤768 统一去掉；padding/gap 一并收到只剩图标的尺寸（沿用 ≤480 的取值），
       否则空掉的文字位会留一圈多余留白。 */
    .mobile-menu-label {
        display: none;
    }

    .mobile-menu-btn {
        padding: 8px 10px;
        gap: 0;
    }

    /* ---------- 头部左侧登录按钮（原 ☰ 菜单位置）----------
       透明底 + 白色人像描边图标（与本地隧道版一致）。44×44 保证触控面积；
       :active 给按压反馈（触屏没有 hover）。 */
    .mobile-login-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        padding: 0;
        flex-shrink: 0;
        border: none;
        border-radius: 50%;
        background: transparent;
        color: #fff;
        cursor: pointer;
    }

    .mobile-login-btn:active {
        transform: scale(0.95);
    }

    /* 已登录态：头部按钮自包含下拉（.mobile-user-menu），fixed 锚在 header 左下。
       top 取 44px 按钮 + 上下 padding + 边框 ≈ 65px 的 header 高度再留 1px。 */
    .mobile-user-menu {
        display: none;
        position: fixed;
        top: calc(env(safe-area-inset-top, 0px) + 66px);
        left: 12px;
        width: max-content;
        max-width: calc(100vw - 24px);
        background: #15151e;
        border: 1px solid rgba(255, 255, 255, 0.09);
        border-radius: 14px;
        box-shadow: 0 12px 36px rgba(0, 0, 0, 0.55);
        overflow: hidden;
        z-index: 1100;
    }

    .mobile-user-menu.open {
        display: block;
    }

    .mobile-user-menu-name {
        padding: 14px 16px;
        border-bottom: 1px solid rgba(255, 255, 255, 0.06);
        color: #f4f4f5;
        font-size: 0.9rem;
        font-weight: 600;
        text-align: center;
    }

    .mobile-user-menu-logout {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        width: 100%;
        padding: 10px 16px;
        background: none;
        border: none;
        color: #ccc;
        font-size: 0.9rem;
        cursor: pointer;
        text-align: center;
    }

    .mobile-user-menu-logout:hover {
        background: rgba(239, 68, 68, 0.15);
        color: #f87171;
    }

    /* ---------- 回到顶部：缩小 + 贴底 ----------
       原来 54×54、bottom: 200px：尺寸比触控下限大 23%，位置更麻烦——200px
       相当于 390×844 屏高的 24%，按钮跑到内容区中部，实测 elementFromPoint
       命中 H3.item-name，压住的是条目标题。
       移动端单手操作时拇指的自然范围是屏幕下半部靠边，所以改成右下角贴底；
       贴底后压的是内容底部边缘，不再挡正经内容。
       44×44 是触控下限，不能再小，所以「变小」主要靠去掉那行 10px 的 TOP
       小字（低于可读字号，且逼着按钮必须更高）和贴底来实现。 */
    .back-to-top {
        width: 44px;
        height: 44px;
        right: 16px;
        /* 安全区：避开 iPhone 底部横条。距底按需求翻倍到 32px */
        bottom: calc(32px + env(safe-area-inset-bottom, 0px));
        border-radius: 12px;
    }

    .back-to-top .back-to-top-label {
        display: none;
    }

    .back-to-top svg {
        width: 20px;
        height: 20px;
    }

    /* 评分星：原约 18px，点星极易点偏 */
    .rating-star {
        min-width: 34px;
        min-height: 34px;
        padding: 6px 4px;
        font-size: 0.95rem;
        box-sizing: border-box;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* 视图切换（卡片 / 表格） */
    .view-btn {
        min-height: 44px;
        padding: 8px 16px;
        box-sizing: border-box;
    }


    /* ---------- D4 弹层宽度：不允许超出视口 ---------- */
    /* .search-form-popup 基础值是 min-width: 550px，min-width 优先级高于
       max-width，一旦脱离 .search-popup-panel 上下文就必然溢出 */
    .search-form-popup,
    .search-popup-panel .search-form-popup {
        min-width: 0;
        width: auto;
        max-width: 100%;
    }

    .search-popup-panel,
    .admin-container,
    .login-container,
    .modal-content,
    .hero-picker-dialog {
        width: calc(100vw - 24px);
        max-width: calc(100vw - 24px);
        box-sizing: border-box;
    }


    /* ---------- D5 安全区（刘海 / 底部横条 / 横屏） ---------- */
    /* 原先只适配了抽屉底部与右侧悬浮面板顶部，这里补齐其余边界 */
    .header-container {
        padding-left: calc(14px + env(safe-area-inset-left, 0px));
        padding-right: calc(14px + env(safe-area-inset-right, 0px));
    }

    .right-sidebar-panel {
        top: calc(14px + env(safe-area-inset-top, 0px));
        right: calc(14px + env(safe-area-inset-right, 0px));
    }

    .sidebar-footer,
    .mobile-nav-footer {
        padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    }

    .grid-container,
    .table-container,
    .pagination {
        padding-left: max(12px, env(safe-area-inset-left, 0px));
        padding-right: max(12px, env(safe-area-inset-right, 0px));
    }

    /* ---------- 卡片：竖排改横排（左封面 / 右上标题两行省略 / 右下标签组） ----------
       这就是精选区那套「新布局」，现在推广到**所有分类**，替代原先两列竖排的
       「卡片组」模式：网格单列、每张卡横排铺满宽度。DOM 各分区共用（_cards.html），
       不动结构、纯靠 grid 定位，所以这里去掉 .featured-section 前缀即可全覆盖。

       .video-section .grid-container 必须一起写：tojav 的分类区（精选与各分类）都在
       .video-section 内，而 styles.css 的 768 断点有同名规则
       `.video-section .grid-container{ repeat(2, minmax(0,1fr)) }`（特异性 0,2,0），
       只写无前缀的 .grid-container（0,1,0）压不过它，tojav 侧会仍是两列竖排。
       两条同特异性、mobile.css 后加载，所以这里能覆盖。 */
    .grid-container,
    .video-section .grid-container {
        grid-template-columns: minmax(0, 1fr);
        gap: 10px;
        max-width: 100%;
    }

    .media-card {
        display: grid;
        /* 两列：左封面 / 右内容。徽章不在移动端显示（见下），所以不再给它留一列，
           右侧 1fr 全给标题与标签组（评分控件由 rating.js 注入 .ntags 内部，跟着走）。 */
        grid-template-columns: 118px minmax(0, 1fr);
        grid-template-rows: auto auto;
        column-gap: 10px;
        row-gap: 6px;
        padding: 8px;
        align-items: start;
    }

    .media-card .image-container {
        grid-column: 1;
        grid-row: 1 / span 2;
        width: 118px;
        /* 封面高度跟随卡片内容高度：卡片用了 align-items: start，封面默认不拉伸，
           只按 aspect-ratio 3/2 得到 78.7px 固定高。标题双行时右侧内容（约 86px）
           高于封面，就会把标签挤出封面下沿、卡片被撑高、封面下方还空一块
           （实测双行卡高 102px、标签超出封面底 7.3px，单行时是 -2.9px 正常）。
           stretch 后封面与右侧内容等高，图片仍 object-fit: cover 裁切填充。
           min-height 让标题单行、内容偏矮时封面不至于压得太扁。 */
        align-self: stretch;
        height: auto;
        aspect-ratio: 3 / 2;
        min-height: 78px;
        border-radius: 8px;
    }

    /* 登录遮罩：四角小尖尖 —— 遮罩自身没有圆角，而它带 backdrop-filter，这类元素
       在有圆角裁剪的父容器里滤镜区域仍是矩形，会在圆角处漏出直角边缘，看着就是
       封面四角各伸出一个小尖。圆角跟随封面（inherit 拿到 image-container 的 8px），
       并去掉毛玻璃：未登录时封面本身已有 blur(3px)（styles.css），遮罩留半透明
       底即可，顺带省掉移动端毛玻璃的合成开销。 */
    .media-card .image-overlay {
        border-radius: inherit;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    /* 锁图标与「登录后查看」按移动端封面缩小：桌面是锁 2rem、文案 0.95rem +
       10px 20px 内边距，放进 118px 宽的封面几乎撑满、很突兀。 */
    .media-card .login-prompt-icon {
        font-size: 0.95rem;
        margin-bottom: 2px;
    }

    .media-card .login-prompt {
        font-size: 0.6rem;
        padding: 2px 6px;
    }

    /* 影片名称：右上，背景去除（桌面 .card-header 带 0.05 白底 + 1px 下边框，
       横排后这条横杠把每张卡顶得发闷）。 */
    .media-card .card-header {
        grid-column: 2;
        grid-row: 1;
        padding: 0;
        background: transparent;
        border-bottom: none;
    }

    /* 最多两行、超出省略：桌面是单行截断（-webkit-line-clamp: 1），横排右侧约 250px
       放得下两行，单行会把长番号整条切掉、读不出片名。.item-name 本身已是
       -webkit-box + vertical，这里只放行数。 */
    .media-card .item-name {
        -webkit-line-clamp: 2;
        line-clamp: 2;
    }

    .media-card .ntags {
        grid-column: 2;
        grid-row: 2;
        align-self: center;
        min-height: 0;
    }

    /* 来源徽章不在移动端显示：它默认 absolute 浮在封面左上角，小封面上被它盖住、
       与新布局冲突；DOM 保留，桌面端照常显示（本轮优化只针对移动端）。 */
    .media-card .ntag--source {
        display: none;
    }

    .footer {
        padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
    }

    .update-toast {
        bottom: calc(16px + env(safe-area-inset-bottom, 0px));
        top: auto;
        left: 50%;
        transform: translateX(-50%) translateY(20px);
        max-width: calc(100vw - 32px);
        padding: 10px 18px;
        font-size: 14px;
        line-height: 1.4;
        border-radius: 10px;
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
    }

    .update-toast.show {
        transform: translateX(-50%) translateY(0);
    }


    /* ---------- D6 hover 依赖的兜底 ----------
       触屏没有hover，原先「hover 才显示」的交互统一改成常显 / 可点 */
    .tojav-page .card-actions,
    .tojav-page .video-actions,
    .tojav-page .overlay-actions {
        opacity: 1;
        transform: none;
    }


    /* ---------- D7 toJAV 头部：☰ 菜单 | logo | 搜索 同一水平线 ----------
       原来三者分两行：logo 占一行，.header-actions（菜单 + 搜索）因为 width: 100%
       被挤到第二行、再靠 space-between 撑到两端。
       现在模板里已把 ☰ 按钮提到 .logo 之前，三者同为 .header-container 的直接
       子元素，这里只需：不换行 + logo 吃掉剩余空间并居中，搜索自然留在右侧。 */
    .header-container {
        flex-wrap: nowrap;
        gap: 10px;
        align-items: center;
    }

    .logo {
        flex: 1 1 auto;
        min-width: 0;      /* flex item 默认 min-width: auto，搜索展开时会被顶出视口 */
        text-align: center;
    }

    .logo a {
        display: inline-flex;
        align-items: center;
        line-height: 1.2;
        /* logo 现在是「双击回顶部」的手势目标（已不带 href）：关掉文本选中与
           长按菜单，免得双击被识别成选中文字、长按弹出「拷贝链接」。 */
        user-select: none;
        -webkit-user-select: none;
        -webkit-touch-callout: none;
        cursor: pointer;
    }

    /* 覆盖 ≤768 断点里的 width: 100% —— 它正是把操作区挤到第二行的原因 */
    .header-actions {
        width: auto;
        justify-content: flex-end;
    }

    /* 展开搜索框时不再需要把 search-wrapper 推到最右（logo 的 flex 已吃掉剩余空间） */
    .header-search-wrapper {
        margin-left: 0;
    }

    /* 登录入口在移动端统一放在 ☰ 抽屉底部，header 里的用户区隐藏后不再占 gap */
    .header-user {
        display: none;
    }

    /* ---------- D9 彻底废掉 header 里「输入框行内展开」这条旧路径 ----------
       ≤768px 搜索改走全屏层后，这里的展开已经没有用途，但原样留着会露馅：
       点（甚至只是按住）放大镜会让按钮拿到焦点，styles.css 的
       .search-box:focus-within input { width: 110px } 随即命中，配上
       transition: width .35s，输入框又自己撑开了。
       所以必须连 :focus-within 一起按住，而不只是忽略 .open。 */
    .header-actions .search-box input,
    .header-actions .search-box.open input,
    .header-actions .search-box:focus-within input {
        width: 0;
        padding: 0;
        opacity: 0;
        pointer-events: none;
        transition: none;
    }

    /* 容器本身也要收干净：input 已经被压成 0 宽，只清边框不清底色的话，
       会剩一个 52×56 的半透明白圆角矩形空壳（比 44px 的按钮宽 8px，
       正好是残留的 padding-right），看起来就是一块凭空的背景。
       放大镜按钮自带 rgba(102,126,234,.25) 的圆形底，去掉容器底色后
       依然是清晰的 44×44 触控目标。 */
    .header-actions .search-box,
    .header-actions .search-box.open,
    .header-actions .search-box:focus-within {
        padding-left: 0;
        padding-right: 0;
        gap: 0;
        border-color: transparent;
        background: transparent;
        box-shadow: none;
    }
}


/* ============ D8. toJAV 移动端全屏搜索层（App 式「新窗口」搜索） ============ */
/* ≤768px 点击放大镜后进入：全屏固定层 + 自动唤起软键盘 + History API 造页面栈，
   使返回键/手势返回只关闭搜索而不退出站点（对应 openMobileSearch / popstate）。
   打开/关闭由 hidden 属性直接切换，不做任何进出场动画。 */
.mobile-search-overlay {
    position: fixed;
    inset: 0;
    z-index: 1300;
    display: none;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    background: #0a0a10;
    padding-top: env(safe-area-inset-top, 0px);
}

.mobile-search-overlay:not([hidden]) {
    display: flex;
}

/* 收起：反向播放同一套圆形揭示，播完由 JS 真正 hidden */

.mobile-search-bar {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    padding: 10px 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.mobile-search-back {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: rgba(255, 255, 255, 0.55);
    cursor: pointer;
    box-sizing: border-box;
}

.mobile-search-back svg {
    width: 22px;
    height: 22px;
}

.mobile-search-back:active {
    background: rgba(255, 255, 255, 0.08);
}

.mobile-search-input {
    flex: 1 1 auto;
    min-width: 0;
    height: 44px;
    padding: 0 14px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 22px;
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.92);
    /* ≥16px 才能避免 iOS 聚焦时整页放大 */
    font-size: 16px;
    /* 去掉 type=search 在 WebKit 下的原生清除按钮，改用自定义的 clear */
    -webkit-appearance: none;
    appearance: none;
}

.mobile-search-input::placeholder {
    color: rgba(255, 255, 255, 0.38);
}

.mobile-search-input:focus {
    outline: none;
    border-color: rgba(255, 185, 56, 0.45);
    background: rgba(255, 255, 255, 0.09);
}

.mobile-search-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 8px 12px calc(20px + env(safe-area-inset-bottom, 0px));
}

/* ---------- 搜索结果：两列卡片组 ----------
   桌面（header 下拉）是「左小图 + 右文字」的横条列表，那套基础样式在 styles.css
   里，保持不动。移动端全屏层内改成两列卡片：封面在上、标题在下。
   容器层 .search-result-grid 由 tojav.js **只在写入全屏层时**包一层，
   所以下面这些规则也只影响移动端，桌面下拉不受牵连。 */
.mobile-search-results .search-result-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

.mobile-search-results .search-result-item {
    display: flex;
    flex-direction: column;
    /* 基础样式 .search-result-item 是桌面横条，带 align-items: center（小图与
       文字垂直居中）。这里改成 column 后若不重置，它管的就是水平方向了：
       子项不再撑满卡片宽度，而是按内容收缩并居中 —— 实测短标题卡片的
       .search-result-info 只有 86px 而不是 176px，标题和标签挤在中间，
       meta 里两个标签还会在窄容器里折行，看着就是「标签显示不完全」。
       拉回 stretch 让内容区占满卡片，标签就能正常排在一行。 */
    align-items: stretch;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.07);
    border-radius: 12px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.04);
    cursor: pointer;
}

/* 基础样式里末项会去掉下边框，卡片模式下要保留一圈完整边框 */
.mobile-search-results .search-result-item:last-child {
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.mobile-search-results .search-result-item:active {
    background: rgba(102, 126, 234, 0.16);
}

.mobile-search-results .search-result-img {
    /* 固定缩略图尺寸 150×100（横排卡片的封面统一大小，不再随卡片宽度拉伸）。
       img 仍是 100%/100% + object-fit: cover，所以不论原图比例都能铺满不畸变。 */
    width: 150px;
    height: 100px;
    flex-shrink: 0;
    /* 列布局里固定宽比卡片内容区窄，居中避免靠左留白 */
    align-self: center;
    border-radius: 0;
    overflow: hidden;
    background: #1a1a2e;
}

.mobile-search-results .search-result-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.mobile-search-results .search-result-info {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 10px 10px;
}

/* 基础样式里标题是单行省略；卡片里给两行再截断，长番号才不会挤成一团 */
.mobile-search-results .search-result-name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    white-space: normal;
    font-size: 0.8rem;
    line-height: 1.4;
    margin-bottom: 6px;
    overflow-wrap: anywhere;
}

.mobile-search-results .search-result-meta {
    gap: 4px;
}


/* 「搜索中…」不是一条结果，不该套卡片外框。
   上面的卡片规则是按 .search-result-item 命中的，loading 项也会被套上
   底色 + 1px 描边 + 圆角，看着像一张空卡片；padding 还被压成 0（卡片的留白
   在内部 .search-result-info 上），spinner 和文字挤在一起。
   这里还原成纯粹的一行提示：无底无框、恢复原本的 20px 内边距和横排居中，
   并让它横跨整行 —— 它是整层的状态提示，不该只占网格半格。 */
.mobile-search-results .search-result-item.search-loading {
    grid-column: 1 / -1;
    background: transparent;
    border: none;
    border-radius: 0;
    flex-direction: row;
    align-content: center;
    padding: 20px;
}

/* ---------- 进出场动画：已全部移除 ----------
   先后试过三版，都没有保留：
     1) View Transitions —— 要为整页截快照，首帧停顿 133ms、平均 37fps；
     2) 从放大镜做圆形 clip-path 扩散 —— 全屏尺寸下观感偏"撑开"；
     3) 整层淡入 + 轻微上移 —— 观感仍然不自然。
   现在直接由 hidden 属性开关，不做任何补间，进出都是瞬时完成。 */

/* 层铺满之后，底下几十张卡片的骨架屏微光还在逐帧合成纯属浪费，
   而它们被这层不透明背景完全挡住，暂停没有任何可见影响。 */
html.mobile-search-open .image-container::before {
    animation-play-state: paused;
}

/* ---------- 跨端：搜索结果封面加载失败的占位 ----------
   utils.js 的 onSearchThumbError 会隐藏破图、插入 .search-no-img，
   这里让占位撑满 .search-result-img —— 否则它只是一行小字飘在左上角：
   桌面下拉里是小方块，移动端卡片里是 16:10 的大图区域。
   之所以放在本文件而不是 style.css / styles.css：那两份主样式高度重复，
   同一条规则写两遍正是要避免的漂移来源，而这个文件两页都会加载。 */
.search-result-img.is-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #1a1a2e;
}

.search-result-img.is-placeholder .search-no-img {
    /* 桌面下拉里 .search-result-img 只有 60px 宽，字号要压到能一行放下；
       移动端卡片是 176px 大图，下面再放大回合适尺寸。 */
    font-size: 0.65rem;
    line-height: 1.25;
    color: rgba(255, 255, 255, 0.35);
    text-align: center;
    padding: 0 3px;
}

.mobile-search-results .search-result-img.is-placeholder .search-no-img {
    font-size: 0.72rem;
}

/* ---------- 默认面板：搜索历史 + 热门搜索 ---------- */
.search-home-section {
    margin-bottom: 20px;
}

.search-home-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 6px 2px 10px;
}

.search-home-title {
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.45);
    letter-spacing: 0.04em;
}

.search-home-clear {
    min-height: 32px;
    padding: 6px 10px;
    border: 0;
    border-radius: 16px;
    background: transparent;
    color: rgba(255, 255, 255, 0.35);
    font-size: 0.75rem;
    cursor: pointer;
}

.search-home-clear:active {
    background: rgba(255, 255, 255, 0.08);
}

.search-home-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* 38px 是标签、44px 是按钮的取舍：再高会让默认面板一屏放不下几个词 */
.search-tag {
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
    min-height: 38px;
    max-width: 100%;
    padding: 8px 14px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 19px;
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.82);
    font-size: 0.82rem;
    cursor: pointer;
    overflow-wrap: anywhere;
}

.search-tag:active {
    background: rgba(255, 158, 61, 0.16);
    border-color: rgba(255, 158, 61, 0.38);
    color: #ffcf7a;
}

.search-home-empty {
    padding: 8px 2px;
    color: rgba(255, 255, 255, 0.3);
    font-size: 0.8rem;
}


/* ============ E. ≤480px：超窄屏 ============ */
@media (max-width: 480px) {
    .data-table td::before {
        flex: 0 0 52px;
    }

    .data-table tbody tr {
        padding: 8px 10px;
    }

    /* 页码更多时缩小一点，避免换行过猛（桌面 36px / 移动端 44px 的折中） */
    .page-link {
        min-width: 40px;
        padding: 0 10px;
    }

    .hero {
        min-height: 240px;
    }
}

/* ============ 移动端分类列表：无限滚动（替代数字分页） ============
   仅 ≤768px 生效：隐藏桌面的数字分页条，改由 JS 注入的「加载更多」哨兵
   驱动滚动加载；桌面端不受影响（仍走 .pagination 数字分页）。 */
@media (max-width: 768px) {
    .pagination {
        display: none;
    }

    /* 返回栏滚动跟随：滚动越过其原位后由 JS 切到 .floating（fixed），内容下滑时
       无需回顶即可返回。
       关键：header 是 sticky、z-index 1000、高约 77px 且常驻顶部，所以这里
       top 由 JS 设成 header 高度，浮在它正下方；若写 top: 0 会被 header 盖住
       （连返回键的点击都会被 header 的 ☰ 拦截）。
       不用纯 CSS sticky：祖先存在 overflow:hidden（移动端兜横向溢出）时 sticky 会失效。
       z-index 50 低于 header(1000) 与弹层(1100/1300)，不会遮挡它们。 */
    .search-result-bar.floating {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 50;
        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
    }

    .load-more-wrap {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 10px;
        padding: 24px 16px 40px;
    }

    .load-more-btn {
        min-width: 160px;
        padding: 12px 20px;
        border: 1px solid rgba(255, 158, 61, 0.5);
        border-radius: 24px;
        background: rgba(255, 158, 61, 0.1);
        color: #ffcf7a;
        font-size: 15px;
        font-weight: 600;
        cursor: pointer;
        box-sizing: border-box;
    }

    .load-more-btn:active {
        background: rgba(255, 158, 61, 0.26);
    }

    .load-more-hint {
        color: rgba(255, 255, 255, 0.55);
        font-size: 14px;
    }
}

/* ============ 移动端详情弹层（图片预览 + 磁力）：B 方案重排 ============
   布局：标题吸顶（2 行截断）+ 图片区（横向 scroll-snap，一张一屏，带 i/n 页码）
   + 磁力按钮吸底（满宽 48px）。仅 ≤768px 生效，桌面弹层完全不变。
   页码由 app.js 的 enhanceDetailMobile 更新。

   重要：index.html 里 app.css 在 mobile.css 之后加载，同特异性的规则会被
   app.css 覆盖（实测图片仍是 240px、padding 也不生效）。所以这里所有选择器
   都统一加 .detail-modal 作用域前缀来抬高特异性，确保移动端规则胜出。 */

/* 页码指示由 JS 无条件插入，桌面端没有对应样式，默认隐藏，避免裸露出「1/3」文字；
   ≤768px 时由下面的媒体查询打开。 */
.detail-modal .detail-page-indicator {
    display: none;
}

@media (max-width: 768px) {
    .detail-modal.detail-modal {
        padding: 14px 10px calc(14px + env(safe-area-inset-bottom, 0px));
    }

    .detail-modal .detail-box {
        width: 100%;
        /* 高度有上限，配合下面 flex:1 + min-height:0 让图片区可收缩，内容不溢出 */
        max-height: 90vh;
        max-height: 90dvh;
        padding: 12px 12px calc(12px + env(safe-area-inset-bottom, 0px));
        display: flex;
        flex-direction: column;
    }

    /* 关闭按钮：44×44 触控区，避免误点 */
    .detail-modal .detail-close {
        top: 4px;
        right: 4px;
        width: 44px;
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 22px;
        color: rgba(255, 255, 255, 0.85);
    }

    /* 标题吸顶：长标题 2 行截断，不再把图片和磁力按钮顶出屏幕 */
    .detail-modal .detail-title {
        position: sticky;
        top: 0;
        z-index: 3;
        flex: 0 0 auto;
        margin: 0 0 10px;
        /* 右侧给关闭按钮留位。注意不能留下内边距：line-clamp 只把高度裁到 2 行，
           padding-bottom 会把第 3 行的顶部又露出来，所以这里显式限高到 2 行。 */
        padding: 0 48px 0 0;
        max-height: 2.8em;   /* = 2 行 × line-height 1.4 */
        background: transparent;
        font-size: 15px;
        line-height: 1.4;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    /* 图片区：占满剩余高度，横向一张一屏滑动（gap 归零，保证 scrollLeft 步进=屏宽） */
    .detail-modal .detail-images-wrap {
        position: relative;
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
    }

    .detail-modal .detail-images {
        flex: 1 1 auto;
        /* 不能只用 min-height:0：图片加载失败/未加载时 height:auto 会算出 0，
           图片区会塌成 0 高，横滑也就废了。给个下限兜住。 */
        min-height: 45vh;
        gap: 0;
        overflow-x: auto;
        overflow-y: hidden;
    }

    .detail-modal .detail-images img {
        flex: 0 0 100%;
        width: 100%;
        /* 用容器高度而非 auto，未加载时也有确定高度；object-fit 保证不变形 */
        height: 100%;
        object-fit: contain;
    }

    /* 页码指示：浮在图片右下角（默认隐藏，移动端才显示） */
    .detail-modal .detail-page-indicator {
        display: block;
        position: absolute;
        right: 10px;
        bottom: 10px;
        padding: 3px 10px;
        border-radius: 999px;
        background: rgba(0, 0, 0, 0.62);
        color: #fff;
        font-size: 12px;
        line-height: 1.6;
        pointer-events: none;
    }

    /* 磁力按钮吸底：满宽、48px 触控高度 */
    .detail-modal .detail-actions {
        flex: 0 0 auto;
        margin-top: 12px;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    .detail-modal .detail-magnet {
        width: 100%;
        min-height: 48px;
        font-size: 16px;
    }
}

/* ============ 移动端卡片标签：只保留「有码无码 / 时间 / 大小」 ============
   去掉列表卡片里的磁力按钮（.ntag--magnet）：登录态（磁力/下载）与未登录态
   （🔒 磁力，data-need-login）都带这个类，故一条规则覆盖两种状态。
   取磁力改由点卡片开详情弹层完成，功能不丢；桌面卡片不受影响，仍显示磁力按钮。 */
@media (max-width: 768px) {
    .media-card .ntag--magnet {
        display: none;
    }
}


/* ============ F. 锁定滚动时的 body  positioning（配合 JS ScrollLock） ============ */
/* position: fixed 是 iOS Safari 上唯一可靠的禁滚方式（overflow:hidden 拦不住
   惯性滚动）。这里统一把它要用的样式写死，避免 JS 里散落内联样式。 */
body.scroll-locked {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
    /* 防止固定后因滚动条消失造成横向跳动 */
    padding-right: 0;
}

/* ============ 搜索结果页顶部「返回」栏（全局：桌面/移动通用） ============
   路由 #/s/<query> 渲染进 main，原先没有返回入口；加一个顶部栏，
   左侧返回箭头（回到进入搜索前的页面），右侧展示搜索关键词。 */
.search-result-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 10px 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    background: #0d0d1a;
}

.search-result-back {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: rgba(255, 255, 255, 0.7);
    cursor: pointer;
    box-sizing: border-box;
}

.search-result-back svg {
    width: 22px;
    height: 22px;
}

.search-result-back:active {
    background: rgba(255, 255, 255, 0.08);
}

.search-result-text {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
    overflow: hidden;
}

.search-result-label {
    flex: 0 0 auto;
    color: rgba(255, 255, 255, 0.5);
    font-size: 13px;
}

.search-result-query {
    color: #fff;
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}


/* =========================================================================
   G. 移动端视觉打磨层 —— 「深夜放映厅」设计语言
   -------------------------------------------------------------------------
   方向：站点原有强调色散落三处且互不相干——导航/焦点紫(#667eea)、分类条红
   (#ff5c5c)、磁力橙(#f0a020)、精选金(#fbbf24)、logo 红橙渐变。移动端统一成
   一套「墨黑片场 + 放映暖光」的电影院语言：
     · 表面收进冷墨色阶：#07070c 基底 / #15151e 弹层 / #14141c 卡面
     · 强调色统一为琥珀暖光（#ff9040 → #ffc857 渐变、#ffb938 单色），与 logo
       渐变、磁力钮、精选金标天然同族，紫红两色退出移动端
     · 动效只用 transform/opacity（合成器路径），触屏交互全部 :active 反馈
   本文件加载于 styles.css/tags.css 之后（同特异性后到先得）；唯一在其之后
   加载的是 app.css，因此与 app.css 重叠的选择器一律加 .detail-modal 等前缀
   抬特异性（沿用本文件既有的做法）。
   全部规则仅 ≤768px 生效，桌面端不受影响。
   ========================================================================= */
@media (max-width: 768px) {

    /* ---------- G1 墨黑基底 ----------
       body 原是紫蓝渐变(#1a1a2e→#16213e)，收成近黑的冷墨；
       顶部一层极淡的暖色辉光模拟放映机打光。辉光放在 body::before
       (position:fixed 独立合成层) 上，不随滚动重绘，也不挡点击。 */
    body.tojav-page {
        background: #07070c;
        -webkit-tap-highlight-color: transparent;
    }

    body.tojav-page::before {
        content: '';
        position: fixed;
        inset: 0;
        z-index: -1;
        pointer-events: none;
        background:
            radial-gradient(120% 46% at 50% -6%, rgba(255, 158, 61, 0.075), transparent 62%),
            linear-gradient(180deg, #0b0b13 0%, #07070c 46%);
    }

    /* ---------- G2 头部 ----------
       底色压暗与页面连成一体，发丝线分隔；logo 字号微收、字距收紧，
       红橙渐变保留（它就是这套暖光语言的源头）。 */
    .header {
        background: rgba(10, 10, 16, 0.96);
        border-bottom-color: rgba(255, 255, 255, 0.06);
    }

    .logo a {
        font-size: 1.5rem;
        letter-spacing: 0.01em;
    }

    /* ---------- G3 轮播：全幅无框 + 琥珀 CTA ----------
       原 .hero 桌面态 width:70% + 底部圆角 + 大阴影，移动端收成通栏；
       底部渐变加深到墨色，让 slide 无缝溶进页面背景。 */
    .hero {
        width: 100%;
        height: 48vh;
        height: 48dvh;
        min-height: 300px;
        margin: 0 0 22px;
        border-radius: 0;
        box-shadow: none;
    }

    .slide-overlay {
        background: linear-gradient(180deg,
                rgba(5, 5, 10, 0.2) 0%,
                rgba(5, 5, 10, 0.38) 52%,
                rgba(7, 7, 12, 0.94) 100%);
    }

    .hero-content {
        padding: 16px 14px 46px;
    }

    .hero-content h1 {
        margin: 10px 0 14px;
        font-size: clamp(1.15rem, 5.4vw, 1.5rem);
        line-height: 1.35;
        letter-spacing: 0.01em;
        text-shadow: 0 2px 20px rgba(0, 0, 0, 0.65);
    }

    .hero-badge {
        padding: 3px 11px;
        border: 1px solid rgba(255, 185, 56, 0.38);
        border-radius: 999px;
        background: rgba(255, 158, 61, 0.14);
        color: #ffcf7a;
        font-size: 0.7rem;
    }

    /* 「立即观看」= 电影票根：琥珀渐变 + 深色文字（原红底白字与磁力钮撞色） */
    .hero-btn {
        border-radius: 999px;
        background: linear-gradient(135deg, #ff9040, #ffc857);
        color: #211405;
        box-shadow: 0 4px 20px rgba(255, 144, 64, 0.28);
    }

    .hero-btn:active {
        transform: scale(0.96);
        box-shadow: 0 2px 10px rgba(255, 144, 64, 0.22);
    }

    /* 进度条与圆点换琥珀；圆点改成「当前项拉长」的胶囊形态，不再是一排圆球 */
    .slider-progress-bar {
        background: linear-gradient(90deg, #ff9040, #ffc857);
    }

    .slider-controls {
        bottom: 14px;
    }

    .dot {
        width: 6px;
        height: 6px;
        border-radius: 999px;
        background: rgba(255, 255, 255, 0.3);
        transition: width 0.3s ease, background-color 0.3s ease;
    }

    .dot.active {
        width: 18px;
        background: #ffb938;
    }

    /* ---------- G4 分区标题 ----------
       桌面 max-width:55% margin:auto 在窄屏下会把标题挤到中线上；改为通栏
       左右 12px（与卡片网格的 D5 边距对齐），标题竖条从紫换成琥珀光柱。 */
    .section-header,
    .featured-controls {
        max-width: none;
        margin-left: 0;
        margin-right: 0;
        padding-left: 12px;
        padding-right: 12px;
        box-sizing: border-box;
    }

    .section-header {
        margin-bottom: 14px;
    }

    .section-header h2 {
        font-size: 1.18rem;
        letter-spacing: 0.02em;
    }

    .section-header h2::before {
        background: linear-gradient(180deg, #ff9040, #ffc857);
    }

    .featured-section .section-header h2::before {
        background: linear-gradient(180deg, #ffc857, #ff9040);
    }

    .view-more {
        color: #ffb938;
        font-weight: 600;
    }

    .view-more:active {
        color: #ffcf7a;
    }

    /* ---------- G5 卡片：墨面 + 发丝线 + 按压反馈 ----------
       原卡面是紫灰渐变(#2d2d44→#1e1e2e) + 大阴影，与新的墨黑基底脱节；
       收成低饱和墨面 + 1px 发丝线，:active 轻微下压给触感（无 hover 依赖，
       纯 transform，合成器友好）。 */
    .media-card {
        background: linear-gradient(165deg, #17171f, #101017);
        border: 1px solid rgba(255, 255, 255, 0.06);
        border-radius: 14px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.32);
        transition: transform 0.16s ease, border-color 0.16s ease;
    }

    .media-card:active {
        transform: scale(0.985);
        border-color: rgba(255, 185, 56, 0.3);
    }

    .media-card .image-container {
        border-radius: 10px;
        background: #0d0d14;
    }

    .media-card .item-name {
        color: #f4f4f6;
        font-weight: 600;
        letter-spacing: 0;
        line-height: 1.45;
    }

    /* 标签组：日期/大小改用等宽数字，横向更整齐；高度微调到 23px 的呼吸感 */
    .media-card .ntags {
        gap: 5px;
    }

    .media-card .ntag {
        height: 23px;
        border-radius: 7px;
        font-variant-numeric: tabular-nums;
    }

    /* ---------- G6 分类快捷条（app.css 的 .cat-tab 是移动端专属组件）----------
       在 app.css 内已改为琥珀 active；这里补触控反馈的过渡时长收敛。 */

    /* ---------- G7 详情弹层（.detail-modal 前缀：app.css 在本文件之后加载） */
    .detail-modal .detail-box {
        background: #101018;
        border-color: rgba(255, 255, 255, 0.08);
        border-radius: 16px;
    }

    .detail-modal .detail-title {
        font-weight: 600;
        letter-spacing: 0.01em;
    }

    .detail-modal .detail-magnet {
        border-radius: 12px;
        background: linear-gradient(135deg, #ff9040, #ffc857);
        color: #211405;
        font-weight: 700;
    }

    .detail-modal .detail-magnet:active {
        transform: scale(0.98);
    }

    /* ---------- G8 登录弹窗：暖光聚焦 ----------
       输入框 focus 从默认蓝改为琥珀描边；登录按钮与「立即观看」同语言。 */
    .login-container {
        background: #101018;
        border: 1px solid rgba(255, 255, 255, 0.08);
        border-radius: 16px;
        box-shadow: 0 18px 60px rgba(0, 0, 0, 0.6);
    }

    .login-header h2 {
        letter-spacing: 0.02em;
    }

    .login-form-group input {
        background: rgba(255, 255, 255, 0.05);
        border: 1px solid rgba(255, 255, 255, 0.1);
        border-radius: 10px;
        color: #f0f0f3;
        transition: border-color 0.18s ease;
    }

    .login-form-group input:focus {
        outline: none;
        border-color: rgba(255, 185, 56, 0.5);
    }

    .login-submit {
        border-radius: 999px;
        background: linear-gradient(135deg, #ff9040, #ffc857);
        color: #211405;
        font-weight: 700;
    }

    .login-submit:active {
        transform: scale(0.98);
    }

    /* ---------- G9 悬浮件：回到顶部 / 抽屉 / 浮动返回栏 ----------
       统一墨面 + 发丝线；回到顶部按压时点亮琥珀。 */
    .back-to-top {
        background: rgba(19, 19, 27, 0.92);
        border: 1px solid rgba(255, 255, 255, 0.09);
        color: rgba(255, 255, 255, 0.72);
    }

    .back-to-top:active {
        color: #ffb938;
        border-color: rgba(255, 185, 56, 0.4);
    }

    .mobile-nav {
        background: #0e0e15;
    }

    .search-result-bar.floating {
        background: rgba(10, 10, 16, 0.97);
    }

    /* ---------- G10 空态 / 加载文案 ----------
       loading-text 与「没有更多了」共用 .loading-text，给一点版式节奏。 */
    .loading-text {
        color: rgba(255, 255, 255, 0.4);
        letter-spacing: 0.05em;
        font-size: 0.85rem;
    }

}

/* =========================================================
   === H 骨架屏：分段加载的占位（全局规则 + 移动端覆盖）===
   =========================================================
   桌面端：flex 纵排（skel-img-wrap 250px + skel-header + skel-tags ≈ 350px，
   与 .media-card 精确一致）。
   移动端（@media max-width:768px）：grid 横排（118px 封面 + 1fr 内容 ≈ 110px 高，
   与移动端 .media-card 的 118px + 1fr grid 对齐）。
   两套骨架卡都用相同 HTML 结构，只靠媒体查询切换 display。*/

.skeleton-card {
    display: flex;
    flex-direction: column;
    background: linear-gradient(165deg, #17171f, #101017);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}

.skel-img-wrap {
    width: 100%;
    height: 250px;
    position: relative;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.04);
    flex-shrink: 0;
}

.skel-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, rgba(255,255,255,0.06), rgba(255,255,255,0.03));
    border-radius: 0;
}

.skel-header {
    padding: 10px 12px;
    background: rgba(255, 255, 255, 0.05);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    flex-shrink: 0;
}

.skel-name {
    height: 18px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.08);
    width: 85%;
}

.skel-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 12px 4px;
    align-content: flex-start;
}

.skel-tag {
    height: 22px;
    border-radius: 7px;
    background: rgba(255, 255, 255, 0.06);
    width: 48px;
}

.shimmer-ready .skel-img,
.shimmer-ready .skel-name,
.shimmer-ready .skel-tag,
.skel-img,
.skel-name,
.skel-tag {
    position: relative;
    overflow: hidden;
}

.skel-img::after,
.skel-name::after,
.skel-tag::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg,
            transparent 0%,
            rgba(255, 255, 255, 0.08) 42%,
            rgba(255, 255, 255, 0.14) 50%,
            rgba(255, 255, 255, 0.08) 58%,
            transparent 100%);
    transform: translateX(-100%);
    animation: skel-shimmer 1.6s ease-in-out infinite;
}

@keyframes skel-shimmer {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}

/* hero 骨架：等比例占位 */
.hero-skeleton {
    width: 100%;
    min-height: 300px;
    margin: 0 0 22px;
    background: linear-gradient(180deg, #1a1a24 0%, #101018 100%);
    display: flex;
    align-items: center;
    justify-content: center;
}

.hero-placeholder {
    color: rgba(255, 255, 255, 0.22);
    font-size: 0.85rem;
    letter-spacing: 0.05em;
}

/* ===== 移动端覆盖：grid 横排，对齐移动端 .media-card ===== */
@media (max-width: 768px) {

    .skeleton-card {
        display: grid;
        grid-template-columns: 118px minmax(0, 1fr);
        grid-template-rows: auto auto;
        column-gap: 10px;
        row-gap: 6px;
        padding: 8px;
        align-items: start;
        border-radius: 14px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.32);
    }

    /* 封面：118px 宽，完全跟随 grid 行高 stretch
       aspect-ratio 设为 auto（覆盖全局的 3/2），让高度由 stretch 决定
       —— 和移动端 .image-container 的 align-self: stretch 语义完全一致 */
    .skeleton-card .skel-img-wrap {
        grid-column: 1;
        grid-row: 1 / span 2;
        width: 118px;
        height: auto;
        aspect-ratio: auto;
        align-self: stretch;
        border-radius: 8px;
        background: rgba(255, 255, 255, 0.07);
    }

    .skeleton-card .skel-img-wrap .skel-img {
        border-radius: 8px;
    }

    /* 右侧内容：标题 + 标签组，flex column 自然撑高
       padding/border 对齐移动端 .card-header / .ntags 的真实高度 */
    .skeleton-card .skel-header {
        grid-column: 2;
        grid-row: 1;
        padding: 10px 0;
        border-bottom: 1px solid rgba(255, 255, 255, 0.08);
        background: transparent;
    }

    .skeleton-card .skel-name {
        height: 20px;
        width: 85%;
    }

    .skeleton-card .skel-tags {
        grid-column: 2;
        grid-row: 2;
        padding: 8px 0 4px;
        gap: 5px;
    }

    .skeleton-card .skel-tag {
        height: 23px;
        width: 42px;
    }

    .hero-skeleton {
        width: 100%;
        height: 48vh;
        height: 48dvh;
        min-height: 300px;
        margin: 0 0 22px;
        border-radius: 0;
        box-shadow: none;
        background: linear-gradient(180deg, #15151e 0%, #07070c 100%);
    }
}

/* ===== 减动效：关闭 shimmer 动画 ===== */
@media (prefers-reduced-motion: reduce) {

    .skel-img::after,
    .skel-name::after,
    .skel-tag::after {
        animation: none;
    }
}

/* =========================================================
   === I. 渲染性能层（仅移动端）：屏外分区跳过渲染 ===
   =========================================================
   首页 9 个 section 只有 1-2 个在视口内，content-visibility:auto
   让浏览器跳过屏外 section 的布局/绘制，首帧渲染成本大幅下降。
   contain-intrinsic-size 给出估算高度（6 卡 × ~150px + 标题 ≈ 950px），
   防止滚动条跳动；auto 前缀让浏览器在首次渲染后记忆真实高度。
   注意：hero 不套用（首屏 LCP 元素必须正常参与渲染）。 */
@media (max-width: 768px) {

    .video-section {
        content-visibility: auto;
        contain-intrinsic-size: auto 950px;
    }
}
