/* ============================================================
   全站自适应增强层 responsive.css
   ------------------------------------------------------------
   作用域：前台主站 / 用户中心 / 后台管理 —— 三套外壳共用同一份。
   加载位置：各布局最末（design.css 之后），因此可覆盖前述样式。

   设计原则：
     1) 桌面端零影响 —— 几乎所有规则都包在 max-width 媒体查询里；
     2) 只用主题变量（--theme-*，一律带兜底值），不写死颜色；
     3) 只解决"小屏可用性"，不改变桌面端的设计语言与配色。

   断点（与 nav.css / layout-base.css / admin.php 内联样式保持一致）：
     1199.98 / 991.98 / 767.98 / 575.98 / 399.98

   移动端数据表格卡片化依赖 assets/js/responsive-tables.js 写入的两个标记：
     · <table class="table-stacked">            —— 该表在窄屏下转为卡片
     · <td data-label="字段名">                 —— 卡片内每个值的字段名
   若某个表格希望始终保持"横向滚动"形态，给它加 class="table-nostack"。
   ============================================================ */

/* ------------------------------------------------------------
   1. 全局溢出守卫
   ------------------------------------------------------------ */
img,
video,
canvas,
embed,
object,
iframe,
svg {
    max-width: 100%;
}

/* 图片按容器等比缩放（行内 style 与更高优先级的选择器不受影响） */
img {
    height: auto;
}

pre,
.pre-scrollable {
    max-width: 100%;
    overflow-x: auto;
}

/* ------------------------------------------------------------
   1b. SortableJS 触屏幽灵元素（.sortable-fallback）
   ------------------------------------------------------------
   触屏拖动走 fallback 模式：克隆被拖元素跟随手指。它由
   assets/js/sortable-touch.js 统一改为挂到 <body>（fallbackOnBody），
   而克隆会连同左外边距一起复制（如二级分类卡片的 .ms-4 = 24px），
   于是幽灵相对源元素整体右移，出现"错位/重影"。这里清零外边距。
   （仅影响拖动瞬间的克隆，不参与正常布局，桌面端原生拖拽不产生它）
   ------------------------------------------------------------ */
.sortable-fallback {
    margin: 0 !important;
}

/* 长 URL / 长英文单词在内容区允许断行 —— 只在窄屏启用，避免影响桌面排版 */
@media (max-width: 767.98px) {
    .container,
    .container-fluid,
    .nav-layout,
    .nav-content,
    .admin-content,
    .admin-card-body {
        overflow-wrap: break-word;
    }
}

/* ------------------------------------------------------------
   2. 数据表格 → 移动端卡片
   ------------------------------------------------------------
   每一行变成一张卡片，字段名在上、取值在下，彻底取消横向滚动。
   无表头的"字段名:取值"明细表不会被卡片化（JS 已跳过），保持原样。
   ------------------------------------------------------------ */
@media (max-width: 767.98px) {

    /* 卡片化之后不再需要横向滚动容器 */
    .table-responsive.is-stacked {
        overflow-x: visible;
    }

    /* ------------------------------------------------------------
       拖动排序的管理表格（.table-nostack）：保持"横向滚动表格"形态。
       必须给最小宽度：否则浏览器会把各列压到视口内（表格不再溢出 →
       没有可滚动内容），操作列被挤到 ~65px、按钮折行堆叠、行高暴涨
       到 3~4 倍，用户既看不到编辑/删除按钮也无法左右滑动。
       ------------------------------------------------------------ */
    table.table-nostack {
        min-width: 640px;
    }

    /* 横向滚动表格里的操作按钮：收紧内边距，保证多个按钮单行排布
       （否则 150px 的操作列放不下 3 个按钮 → 折行 → 行高翻倍） */
    table.table-nostack td .btn {
        padding: 0.25rem 0.45rem;
        min-width: 34px;
        min-height: 34px;
        text-align: center;
    }

    /* ------------------------------------------------------------
       拖动抓手（分类卡片头 + 表格行内的抓手）：
       把该区域的触摸手势完全交给 SortableJS，浏览器不得接管。
       若保留默认的 touch-action:auto，手指一移动就被判为"滚动"：
         · 分类卡片头 → 拖动被 touchcancel 打断（按不住、拖不动）
         · 表格行抓手 → 拖动与横向滚动互相争夺，拖动期间页面/表格
           也在滚动，而幽灵元素按视口坐标定位 → 与手指错开（错位）
       抓手只占 40px 列宽，要横向滚动表格时从其它列滑动即可。
       ------------------------------------------------------------ */
    .drag-handle,
    .admin-card-header,
    .card-header {
        touch-action: none;
        -webkit-user-select: none;
        user-select: none;
    }

    /* 抓起热区放大：抓手图标本身只有 ~13px，手指几乎无法精准命中
       （表现为"按上去没反应"）。用伪元素把可点区扩到约 30px，
       不改动元素尺寸，行高与图标位置保持原样。
       注意必须用 ::after —— 抓手是 <i class="bi bi-grip-vertical">，
       图标本身由 Bootstrap Icons 的 ::before 渲染，占用 ::before 会
       把图标清空。 */
    .drag-handle {
        position: relative;
    }

    .drag-handle::after {
        content: '';
        position: absolute;
        top: -8px;
        right: -8px;
        bottom: -8px;
        left: -8px;
    }

    .table-stacked {
        display: block;
        width: 100%;
        margin-bottom: 0;
    }

    .table-stacked > thead {
        display: none;
    }

    .table-stacked > tbody {
        display: block;
    }

    /* 单行 = 单卡片 */
    .table-stacked > tbody > tr,
    .table-stacked > tbody > tr:hover {
        display: block;
        padding: 10px 12px;
        margin: 0 0 10px;
        background-color: var(--theme-card-bg, #ffffff);
        border: 1px solid var(--theme-border, #e5e7eb);
        border-radius: 10px;
        box-shadow: var(--theme-shadow-sm, 0 1px 2px rgba(0, 0, 0, .05));
    }

    /* 单元格 = 卡片内的一段"字段名 / 值" */
    .table-stacked > tbody > tr > td {
        display: block;
        width: auto;
        padding: 5px 0 !important;
        border: 0 !important;
        border-bottom: 1px dashed var(--theme-border-light, var(--theme-border, #e5e7eb)) !important;
        text-align: left !important;
        vertical-align: top;
        white-space: normal !important;
        font-size: .875rem;
        color: var(--theme-text-primary, #111827);
    }

    .table-stacked > tbody > tr > td:last-child {
        padding-bottom: 0 !important;
        border-bottom: 0 !important;
    }

    /* 字段名（由 JS 依据表头写入 data-label）；空表头不显示 */
    .table-stacked > tbody > tr > td[data-label]:not([data-label=""])::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 3px;
        font-size: .68rem;
        font-weight: 700;
        letter-spacing: .02em;
        color: var(--theme-text-muted, #6b7280);
    }

    /* 卡片内文本不再截断，长链接自动换行 */
    .table-stacked .text-truncate,
    .table-stacked .link-url,
    .table-stacked .article-url,
    .table-stacked td > a {
        max-width: none !important;
        overflow: visible !important;
        white-space: normal !important;
        text-overflow: clip !important;
    }

    /* 行内操作按钮：允许换行、保持可点面积 */
    .table-stacked > tbody > tr > td > .btn,
    .table-stacked > tbody > tr > td > .btn-group,
    .table-stacked > tbody > tr > td > form {
        margin: 0 6px 6px 0;
    }

    .table-stacked > tbody > tr > td .btn-group {
        flex-wrap: wrap;
        gap: 4px;
    }

    .table-stacked .btn-sm {
        min-height: 34px;
    }

    /* 条纹表：卡片内部不再叠加条纹底色 */
    .table-stacked.table-striped > tbody > tr:nth-of-type(odd) > td {
        background-color: transparent;
    }

    /* 空状态（colspan 整行）居中显示 */
    .table-stacked > tbody > tr.responsive-row-full {
        padding: 16px 12px;
    }

    .table-stacked > tbody > tr.responsive-row-full > td {
        padding: 0 !important;
        border-bottom: 0 !important;
        text-align: center !important;
    }

    .table-stacked > tbody > tr.responsive-row-full > td::before {
        content: none !important;
        display: none !important;
    }
}

/* ------------------------------------------------------------
   2.1 固定高度的滚动面板：手机端解除限高
   ------------------------------------------------------------
   桌面端由行内 style 限定高度（如后台"点击排行 TOP 20"卡片、邀请码列表），
   手机端表格已卡片化，再套一层小滚动框反而难用，故解除高度限制。
   ------------------------------------------------------------ */
@media (max-width: 767.98px) {
    .scroll-panel {
        max-height: none !important;
        overflow: visible !important;
    }
}

/* ------------------------------------------------------------
   3. 工具栏 / 按钮组 / 分页
   ------------------------------------------------------------ */
@media (max-width: 767.98px) {
    /* 卡片头 / 内容头：标题与操作按钮换行，避免挤出容器 */
    .admin-card-header,
    .admin-card-header.d-flex,
    .card-header,
    .dashboard-content-header,
    .cat-block-header {
        flex-wrap: wrap;
        gap: .5rem;
    }

    /* 前台列表页头部的"筛选 / 排序"工具条 */
    .nav-content .d-flex.justify-content-between,
    .nav-content .d-flex.justify-content-end {
        flex-wrap: wrap;
        gap: .5rem;
    }
}

@media (max-width: 575.98px) {
    /* 分段按钮组在极窄屏允许换行（如"网址 / 文章"切换），避免撑破容器 */
    .btn-group {
        flex-wrap: wrap;
        gap: 4px;
    }

    .btn-group > .btn {
        border-radius: var(--theme-radius-sm, 8px) !important;
    }

    /* 分页在手机端换行居中 */
    .pagination {
        flex-wrap: wrap;
        row-gap: .25rem;
    }
}

/* ------------------------------------------------------------
   4. 栅格：固定列宽（无断点前缀的 col-3/4/6）在手机上改为整行
   ------------------------------------------------------------ */
@media (max-width: 575.98px) {
    .row > .col-1,
    .row > .col-2,
    .row > .col-3,
    .row > .col-4,
    .row > .col-5,
    .row > .col-6,
    .row > .col-7,
    .row > .col-8,
    .row > .col-9,
    .row > .col-10,
    .row > .col-11 {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

/* ------------------------------------------------------------
   5. 弹窗 / 下拉 / 提示
   ------------------------------------------------------------ */
@media (max-width: 575.98px) {
    .modal-dialog {
        margin: .5rem;
    }

    .modal-header,
    .modal-body,
    .modal-footer {
        padding-left: 1rem;
        padding-right: 1rem;
    }

    /* 弹窗底部按钮整行排列，更好点 */
    .modal-footer {
        flex-wrap: wrap;
        gap: .5rem;
    }

    .modal-footer > .btn {
        flex: 1 1 auto;
    }

    /* 下拉菜单不要顶出屏幕 */
    .dropdown-menu {
        max-width: calc(100vw - 1.5rem);
    }

    .toast-container {
        max-width: calc(100vw - 1.5rem);
    }
}

/* ------------------------------------------------------------
   6. 触摸设备：放大可点区域
   ------------------------------------------------------------ */
@media (hover: none) and (pointer: coarse) {
    .pagination .page-link {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 40px;
        min-height: 40px;
    }

    .form-check-input {
        width: 1.25em;
        height: 1.25em;
        margin-top: .15em;
    }
}

/* ------------------------------------------------------------
   7. iOS 惯性滚动
   ------------------------------------------------------------ */
.table-responsive,
.modal-body,
.modal-dialog-scrollable .modal-body,
.nav-sidebar,
.admin-sidebar,
.sidebar-nav,
.dropdown-menu {
    -webkit-overflow-scrolling: touch;
}
