/* ========== 播放页 ========== */
/*
 * 移动端播放页不放全站导航栏（body.is-play-page header 直接 display:none），
 * 返回入口改由页面内容里的 .play-back-bar 承担（播放器正上方，见 vodplay.html）。
 * 原因：固定导航栏压在视频上方，移动端浏览器接管播放器后滚动会和它抢合成层（一闪一闪），
 * 视频被完全盖住还会被自动切进画中画；整条隐藏比降级改造更干净，导航栏本身零改动。
 * PC 端一律不介入：导航栏、body 的 padding-top(90px)、下面 .play-container 的负 margin 全部保持原样。
 * is-play-page 由 layout.html 根据 PlayController 放进 model 的 playPage 追加到 <body>。
 */

/* 播放器上方的返回行：只在移动端播放页露出来，其余场景（含 PC 播放页）一律隐藏 */
.play-back-bar {
    display: none;
}

.play-page-main {
    background-color: #fff;
}

.play-container {
    margin-top: -20px;              /* 抵消 body padding-top(90px) 比导航栏(70px) 多出来的 20px 留白 */
    padding-bottom: 60px;
    max-width: 1350px;
}

/* 播放器区域 */
.player-section {
    margin-bottom: 20px;
}

/* 播放器严格待在 .play-main 里：宽度 = 100%，不做任何负边距突破容器 */
.player-wrapper {
    background-color: #000;
    overflow: hidden;
    position: relative;
    z-index: 1;
    /* 兜底：旧版 Vivo 等不支持 aspect-ratio 的 WebView（Chrome < 88），
       用 padding-bottom 撑出 16:9，否则容器高度坍缩为 0，视频框不可见 */
    height: 0;
    padding-bottom: 56.25%;
}

/* 现代浏览器改用 aspect-ratio，覆盖上面的 padding 兜底 */
@supports (aspect-ratio: 16 / 9) {
    .player-wrapper {
        height: auto;
        padding-bottom: 0;
        aspect-ratio: 16 / 9;
    }
}

.player-content-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

/* ArtPlayer 容器：铺满舞台，播放器根节点 .art-video-player 会自动填满它 */
.artplayer-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
}

/* iframe 解析线路：铺满舞台 */
.player-iframe {
    width: 100%;
    height: 100%;
    border: none;
    display: block;
}

.player-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    width: 100%;
    height: 100%;
    color: #666;
    font-size: 15px;
}

/* 首屏异步解析播放地址期间的加载占位：播放器实例还没创建，用轻量 spinner + 文案，
   解析到手后由 createArt 的 teardown 清空容器自动移除，失败则由 fallbackTip 覆盖 */
.player-loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    color: #999;
    font-size: 14px;
}

.player-loading-spinner {
    width: 34px;
    height: 34px;
    border: 3px solid rgba(255, 255, 255, 0.2);
    border-top-color: #ff9800;
    border-radius: 50%;
    animation: player-loading-spin 0.8s linear infinite;
}

@keyframes player-loading-spin {
    to { transform: rotate(360deg); }
}

/*
 * 影片信息卡片：与播放器、播放线路拼成一整块，所以去圆角、去阴影。
 * 阴影会在接缝处糊出一条灰边——它的上沿同时紧贴着播放器下沿和侧栏下沿，
 * 三块之间的分隔改由发丝线承担，见下面 .play-layout > .play-info-card 的 border-top。
 */
.play-info-card {
    background-color: transparent;
    border-radius: 0;
    box-shadow: none;
    margin-bottom: 20px;
    overflow: hidden;
}

/* 信息区 */
.play-info-title-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 8px;
}

.play-vod-name {
    font-size: 25px;
    font-weight: 700;
    color: #1a1a1a;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex: 0 1 auto;
    line-height: 1.4;
    transition: color 0.2s;
}

.play-vod-name:hover {
    color: #ff9800;
}

.play-report-btn {
    display: inline-flex;
    align-items: center;
    align-self: center;
    margin-left: auto;
    gap: 4px;
    padding: 5px 14px;
    font-size: 12px;
    color: #999;
    background-color: #fafafa;
    border: 1px solid #eee;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s;
    white-space: nowrap;
    flex-shrink: 0;
    line-height: 1.5;
}

/* 悬停反馈只给能悬停的设备：触屏点按后 :hover 会粘在元素上（不跳页的按钮尤其明显） */
@media (hover: hover) {
    .play-report-btn:hover {
        color: #e53935;
        border-color: #e53935;
        background-color: #fff5f5;
    }
}

/* 触屏点按反馈：替代被收掉的 :hover */
.play-report-btn:active {
    color: #e53935;
    border-color: #e53935;
}

.play-info-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 13px;
    color: #999;
}

/* 集数：作为片名后缀，紧跟在影片名称之后 */
.play-meta-ep {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 25px;
    font-weight: 500;
    color: #888;
}

/* 第二排元信息：备注 / 年份 / 地区 / 类型，条目之间用发丝点分隔 */
.play-meta-item + .play-meta-item::before {
    content: '·';
    color: #ddd;
    margin-right: 8px;
    user-select: none;
}

/* 导航区：位于影片名称上方；PC 端宽度与播放器一致
   （侧栏固定 296px、.play-layout 的 gap 为 0，故播放器宽 = 100% - 296px） */
.play-info-nav {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 0;
    width: calc(100% - 296px);
    box-sizing: border-box;
}

.play-info-nav .play-nav-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /*padding: 10px 16px;*/
    font-size: 13px;
    color: #555;
    background-color: #fafafa;
    border: 1px solid #eee;
    border-radius: 8px;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.2s;
    white-space: nowrap;
}

.play-info-nav .play-nav-btn:hover {
    color: #ff9800;
    border-color: #ff9800;
    background-color: #fffaf0;
}

.play-info-nav .play-nav-btn.disabled {
    color: #ccc;
    cursor: not-allowed;
    background-color: #fafafa;
    border-color: #f0f0f0;
}

.play-info-nav .play-nav-btn.disabled:hover {
    color: #ccc;
    border-color: #f0f0f0;
    background-color: #fafafa;
}

/* 报错弹窗 */
.report-modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 9999;
    align-items: center;
    justify-content: center;
}

.report-modal.show {
    display: flex;
}

.report-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.4);
}

.report-dialog {
    position: relative;
    background-color: #ffffff;
    border-radius: 12px;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
    width: 380px;
    max-width: calc(100% - 32px);
    overflow: hidden;
    animation: dialogIn 0.25s ease;
}

@keyframes dialogIn {
    from {
        opacity: 0;
        transform: translateY(-20px) scale(0.96);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.report-dialog-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 18px 20px;
    font-size: 16px;
    font-weight: 600;
    color: #222;
    border-bottom: 1px solid #f0f0f0;
}

.report-close-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: auto;
    width: 28px;
    height: 28px;
    border: none;
    background: none;
    color: #999;
    cursor: pointer;
    border-radius: 6px;
    transition: all 0.2s;
}

.report-close-btn:hover {
    background-color: #f5f5f5;
    color: #333;
}

.report-dialog-body {
    padding: 20px;
}

.report-info-row {
    display: flex;
    align-items: center;
    padding: 10px 0;
}

.report-info-row + .report-info-row {
    border-top: 1px solid #f8f8f8;
}

.report-label {
    flex-shrink: 0;
    width: 48px;
    font-size: 13px;
    color: #999;
}

.report-value {
    font-size: 14px;
    color: #222;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.report-remark-row {
    margin-top: 12px;
    position: relative;
}

.report-remark-input {
    width: 100%;
    height: 72px;
    padding: 10px 12px;
    font-size: 13px;
    color: #333;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    resize: none;
    outline: none;
    box-sizing: border-box;
    transition: border-color 0.2s;
    font-family: inherit;
}

.report-remark-input:focus {
    border-color: #ff9800;
}

.report-remark-input::placeholder {
    color: #bbb;
}

.report-remark-count {
    position: absolute;
    right: 10px;
    bottom: 8px;
    font-size: 11px;
    color: #bbb;
}

.report-dialog-footer {
    display: flex;
    gap: 10px;
    padding: 0 20px 20px;
}

.report-cancel-btn {
    flex: 1;
    padding: 10px;
    font-size: 14px;
    color: #666;
    background-color: #f5f5f7;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
}

.report-cancel-btn:hover {
    background-color: #eee;
}

.report-confirm-btn {
    flex: 1;
    padding: 10px;
    font-size: 14px;
    color: #fff;
    background-color: #ff9800;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
}

.report-confirm-btn:hover {
    background-color: #f57c00;
}

/* 播放导航按钮 */
.play-nav-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 8px 16px;
    font-size: 13px;
    color: #555;
    background-color: #f5f5f7;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.2s;
    white-space: nowrap;
}

.play-nav-btn:hover {
    color: #ff9800;
    border-color: #ff9800;
    background-color: #fff8f0;
}

.play-nav-btn.disabled {
    color: #ccc;
    cursor: not-allowed;
    background-color: #fafafa;
    border-color: #eee;
}

.play-nav-btn.disabled:hover {
    color: #ccc;
    border-color: #eee;
    background-color: #fafafa;
}

/* 剧集列表 */
.play-episodes-section {
    background-color: #f8f8f8;
    padding: 24px;
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.source-tabs {
    display: flex;
    align-items: center;
    gap: 20px;
    margin: 16px 0;
    padding-bottom: 16px;
    border-bottom: 1px solid #f0f0f0;
    -webkit-overflow-scrolling: touch;
}

.source-tab {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 0;
    font-size: 15px;
    color: #666;
    background: none;
    border: none;
    cursor: pointer;
    transition: all 0.2s ease;
    position: relative;
}

@media (hover: hover) {
    .source-tab:hover {
        color: #333;
    }
}

.source-tab.active {
    color: #ff9800;
    font-weight: 700;
}

.source-tab.active::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 50%;
    transform: translateX(-50%);
    width: 24px;
    height: 3px;
    background-color: #ff9800;
    border-radius: 2px;
}

.episode-grid {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 10px;
}

.episode-btn {
    display: block;
    text-align: center;
    padding: 12px 4px;
    font-size: 14px;
    color: #333;
    background-color: #f5f5f7;
    border-radius: 6px;
    transition: all 0.2s ease;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
    border: none;
}

@media (hover: hover) {
    .episode-btn:hover {
        color: #fff;
        background-color: #ff9800;
        transform: translateY(-2px);
    }
}

/* 触屏点按反馈：轻压变深灰，松手即恢复，不会像 :hover 那样粘住 */
.episode-btn:active {
    background-color: #e6e6ea;
}

.episode-active {
    color: #fff !important;
    background-color: #ff9800 !important;
    font-weight: 600;
}

.episode-hidden {
    display: none !important;
}

/* ArtPlayer 未能创建时的兜底提示 */
.player-fallback-tip {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
    padding: 0 20px;
    font-size: 14px;
    color: #999;
    text-align: center;
}

/* 切集清空播放参数后：ArtPlayer 收不到 timeupdate，底部条会一直挂着上一集的进度与时间，
   整条隐藏到新集第一次 timeupdate 刷新完（由 play-router.js 的 setProgressUiHidden 控制）。
   这不是遮罩层，只是暂时收起原生组件的脏状态；迷你进度线类名各版本不一致，用属性选择器一并覆盖 */
.player-cleared .art-bottom,
.player-cleared .artplayer-bottom,
.player-cleared [class*="mini-progress"],
.player-cleared [class*="progress-mini"] {
    opacity: 0 !important;
    visibility: hidden !important;
}

/* ========== PC 端左右分栏：播放器在左，播放线路在右 ========== */
/*
 * 三个约束同时满足：
 * ① 侧栏高度 == 播放器高度：.play-side 用 position:relative 占位，卡片绝对定位脱离文档流，
 *    于是它对 flex 行高的贡献为 0，行高完全由播放器的 aspect-ratio 16/9 决定；
 *    卡片 inset:0 填满即与播放器严格等高，选集区 flex:1 + min-height:0 承接内部滚动。
 *    注意 .player-section 的 margin-bottom 必须归零——flex item 建立独立格式化上下文，
 *    子元素外边距不折叠，留着 20px 会让侧栏比播放器高出一截。
 * ② 紧贴播放器：.play-layout 的 gap 为 0，卡片去圆角去阴影，与黑色播放器形成硬边。
 * ③ 信息卡跨满整行：flex-wrap:wrap + flex-basis:100% 让它换到第二行，
 *    宽度 = 播放器 + 侧栏；移动端再用 order 调回「播放器 → 信息卡 → 播放线路」。
 *
 * 三区都不越出 .container 的内容区（1350 - 12 * 2 = 1326px），左右边缘天然与导航栏对齐。
 *
 * .source-tabs / .episode-grid / .episode-btn 是 detail.html 也在用的公共类，
 * 这里全部用 .play-side 限定作用域，避免样式泄漏到详情页。
 */
.play-layout {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0;
}

.play-main {
    order: 1;
    flex: 1 1 auto;
    min-width: 0;                   /* 否则播放器不收缩，长片名会把侧栏挤没 */
}

.play-main .player-section {
    margin-bottom: 0;
}

/* 侧栏 296px：播放器宽 = 1326 - 296 = 1030px（16:9 → 高约 579px），侧栏与之等高 */
.play-side {
    order: 2;
    position: relative;
    flex: 0 0 296px;
    min-width: 0;
}

.play-side .play-side-card {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: flex;
    flex-direction: column;
    /*
     * padding 必须写在这一条里：同一元素还挂着 .play-episodes-section，
     * 那条规则一直在兜底（PC 24px / 移动端 16px）。把这里注释掉不等于 0，
     * 而是回落到 24px；写在这里（0,2,0）才压得住它（0,1,0）。
     */
    padding: 16px;
    border-radius: 0;               /* 紧贴播放器，不要圆角 */
    box-shadow: none;
}

.play-side .vod-section-header {
    flex-shrink: 0;
    margin-bottom: 10px;
}

.play-side .vod-section-title {
    font-size: 17px;
}

/*
 * 「播放线路」标题行最右侧的排序开关。
 * 这里不加 .play-side 前缀：.episode-grid / .source-tabs 是 detail.html 也在用的公共类，
 * 必须靠作用域隔离；而 .episode-order-btn 是本次新增的独有类名，全站只此一处，不存在泄漏。
 */
.episode-order-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;              /* .vod-section-header 是 flex，auto 外边距把它推到行尾 */
    flex-shrink: 0;
    padding: 3px 8px;
    font-size: 12px;
    color: #999;
    white-space: nowrap;
    background-color: #f5f5f7;      /* 沿用 .episode-btn 的底色，风格保持一致 */
    border: none;
    border-radius: 12px;
    cursor: pointer;
    transition: color 0.2s ease, background-color 0.2s ease;
}

@media (hover: hover) {
    .episode-order-btn:hover {
        color: #ff9800;
        background-color: #fff1dc;
    }
}

/* 倒序时高亮成主题色，并把箭头翻向上 */
.episode-order-btn.order-desc {
    color: #ff9800;
}

.episode-order-icon {
    transition: transform 0.2s ease;
}

.episode-order-btn.order-desc .episode-order-icon {
    transform: rotate(180deg);
}

/* 线路标签一排三个、各占三分之一、文字居中；超过三个自动折到下一排 */
.play-side .source-tabs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    flex-shrink: 0;
    gap: 6px 0;
    margin: 0 0 12px;
    padding-bottom: 12px;
    overflow: visible;
}

.play-side .source-tab {
    width: 100%;
    justify-content: center;        /* .source-tab 本身是 flex，这里把文字居中 */
    padding: 6px 2px;
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.play-side-scroll {
    position: relative;             /* 选集按钮 offsetTop 的基准，供自动定位当前集使用 */
    flex: 1 1 auto;
    min-height: 0;                  /* flex 列方向必须置 0，否则 overflow 不生效 */
    overflow-y: auto;
    overscroll-behavior: contain;   /* 滚到底不再带动整页滚动 */
    padding-right: 4px;
    margin-right: -4px;             /* 滚动条占位补偿，让 4 列网格宽度不被滚动条吃掉 */
}

.play-side-scroll::-webkit-scrollbar {
    width: 6px;
}

.play-side-scroll::-webkit-scrollbar-track {
    background: transparent;
}

.play-side-scroll::-webkit-scrollbar-thumb {
    background-color: #e0e0e0;
    border-radius: 3px;
}

.play-side-scroll::-webkit-scrollbar-thumb:hover {
    background-color: #ccc;
}

/* 选集 4 列：296px 侧栏去掉 16px 内边距后每格约 60px，放得下「第 12 集」 */
.play-side .episode-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}

.play-side .episode-btn {
    padding: 10px 2px;
    font-size: 13px;
}

/*
 * 「展开全部」只占一个格子，不跨行——移动端它要正好落在最后一排的最后一格。
 * 折叠只在移动端启用（PC 端侧栏与播放器等高、内部滚动，全部铺开更好选集），
 * 所以默认藏起来：initEpisodeGrids 在 load 事件里才跑，不藏的话 PC 端会先闪出一个多余格子。
 * 由 applyVisibleLimit 用内联 display:block 显式放出。
 */
.play-side .episode-expand-btn {
    display: none;
    color: #ff9800;                 /* 橙色文字点明这是操作，不是某一集 */
}

/* 信息卡换到第二行，宽度 = 播放器 + 侧栏 */
.play-layout > .play-info-card {
    order: 3;
    flex: 0 0 100%;
    margin-top: 0;
    border-top: 1px solid #f3f3f3;
}

/*
 * 推荐模块：复用全站 .vod-section（标题 + 海报网格），这里只处理它与播放页的接缝。
 * 上沿用发丝线分隔，延续「播放器 / 侧栏 / 信息卡」拼成一整块的做法；
 * 片段自带的 45px 下外边距收掉，尾部留白统一交给 .play-container 的 padding-bottom。
 * 选择器带上 .play-container 前缀，特异性 (0,2,0) 才压得住 common.css 里的 .vod-section。
 */
.play-container .vod-section {
    margin-bottom: 0;
    padding-top: 20px;
    border-top: 1px solid #f3f3f3;
}

/* ========== 中等屏幕：侧栏收窄，选集降为 3 列 ========== */
@media (max-width: 1200px) {
    .play-side {
        flex-basis: 280px;
    }

    .play-side .episode-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .play-info-nav {
        width: calc(100% - 280px);
    }
}

/* ========== 移动端：取消分栏，回到「播放器 → 信息卡 → 播放线路」 ========== */
@media (max-width: 768px) {
    /*
     * 播放页专属：导航栏回到文档流，只留 首页 + 搜索 / 收藏 / 历史 一行。
     * position 改 relative 而不是 static——只有定位元素的 z-index 才生效，
     * 导航栏和它挂着的下拉面板必须压在播放器（.player-wrapper 的 z-index:1）之上；
     * common.css 的 top:0 / left:0 在相对定位下等于不偏移，不用管。
     * 外层 <header> 是 layout.html 的片段宿主，内层那个才来自 public/header.html，
     * 两个都得改：外层仍然 fixed 的话，内层会被它一起钉在视口顶部。
     */
    body.is-play-page {
        padding-top: 0;
    }

    /*
     * 移动端播放页不放导航栏：内外两层 <header>（layout.html 的片段宿主 + public/header.html）
     * 一起隐藏，返回入口由 .play-back-bar 接管。隐藏而非降级，导航栏样式零侵入。
     */
    body.is-play-page header {
        display: none;
    }

    .play-container {
        margin-top: 0;              /* 导航栏已隐藏，没有多余留白要抵消 */
        padding-bottom: 40px;
    }

    /*
     * 返回行：与全站同一种设计语言——白底 + 发丝下边框、橙色折角箭头 + 正文灰黑文字；
     * 用和播放器同款的负边距公式通栏，内容 12px 内 padding 与下方 gutter 对齐，
     * 与通栏播放器拼成「返回行 → 黑屏视频」的整幅分层。
     */
    .play-back-bar {
        display: flex;
        align-items: center;
        margin-left: calc(50% - 50vw);
        margin-right: calc(50% - 50vw);
        padding: 0 12px;
        height: 44px;
        box-sizing: border-box;
        background-color: #fff;
        border-bottom: 1px solid #f3f3f3;
    }

    .play-back-link {
        display: inline-flex;
        align-items: center;
        gap: 2px;
        color: #333;
        font-size: 14px;
        text-decoration: none;
    }

    .play-back-link svg {
        color: #ff9800;             /* 折角箭头用主题橙，文字保持正文灰黑 */
    }

    /* 触屏反馈用 :active 不用 :hover——:hover 在手机上点完会粘住 */
    .play-back-link:active {
        opacity: 0.7;
    }

    /*
     * 取消分栏：三块纵向堆叠，order 决定「播放器 → 信息卡 → 播放线路」。
     * 这条不能丢：行方向下 .play-main 会和 .play-info-card 挤在同一行
     * （播放器缩成半屏、上一集 / 下一集被推到播放器右侧），.play-side 也会缩成内容宽。
     */
    .play-layout {
        flex-direction: column;
        flex-wrap: nowrap;          /* 列方向下 wrap 无意义，显式关掉防残留 */
    }

    .play-main {
        order: 1;
        flex: 0 0 auto;             /* 复位 PC 行方向的 flex:1 1 auto */
    }

    /*
     * 播放器通栏：calc(50% - 50vw) 恒等于「负的容器左右 gutter」，
     * 不管 gutter 是 10px 还是 12px 都精确贴满屏幕两边，且不产生横向溢出；
     * 仅移动端生效，信息卡 / 播放线路 / 相关推荐仍保持 gutter 内缩进。
     */
    .play-main .player-section {
        margin-left: calc(50% - 50vw);
        margin-right: calc(50% - 50vw);
    }

    /* 三区都在容器内容区里，左右边缘天然对齐，不再需要负边距去凑通栏 */
    .play-layout > .play-info-card {
        order: 2;
        flex: 0 0 auto;             /* 列方向下 flex-basis 会变成高度，必须复位 */
        margin-top: 0;
    }

    .play-side {
        order: 3;
        position: static;
        flex: 0 0 auto;
        width: auto;
        height: auto;               /* 复位 PC 的固定高，高度交还给内容 */
        margin-bottom: 20px;
    }

    /*
     * 移动端取消卡片外观：去背景色、去圆角、去阴影，铺满内容区宽度。
     * 内边距归零——标题行、线路标签、选集网格三者与卡片同宽，
     * 左边缘与上方播放器严丝合缝对齐（都在 .container 的 12px gutter 内）。
     */
    .play-side .play-side-card {
        position: static;
        display: block;
        height: auto;
        overflow: visible;          /* 复位 PC 的裁剪，标题行 / 线路标签不被切掉 */
        padding: 0;
        /* 左右归零保持与播放器左缘对齐；底部单独补一点留白，
           否则最后一排选集按钮会紧贴卡片底边，显得拥挤 */
        padding-bottom: 1px;
        background-color: transparent;
        border-radius: 0;
        box-shadow: none;
    }

    .play-side-scroll {
        overflow: visible;
        height: auto;               /* 复位 PC 的 flex:1 滚动区高度 */
        padding-right: 0;
        margin-right: 0;
    }

    /* 线路标签恢复横向滚动的一排 */
    .play-side .source-tabs {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: 12px;
        margin: 12px 0;
        padding-bottom: 8px;
        -webkit-overflow-scrolling: touch;
    }

    .play-side .source-tab {
        width: auto;
        flex-shrink: 0;
        justify-content: flex-start;
        padding: 6px 0;
        overflow: visible;
    }

    /* 统一 3 列：折叠时 5 集 + 「展开全部」正好排满两排，按钮落在最后一排的最后一格。
       gap 不用重复声明，基础规则里已经是 8px */
    .play-side .episode-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .play-info-nav {
        width: auto;                /* 移动端整行铺满，不再对齐播放器宽度 */
        /*padding: 10px 16px;*/
        gap: 8px;
    }

    /* ========== 移动端：播放器控制栏缩小 ========== */
    .art-video-player .art-controls {
        padding: 0 4px !important;
    }

    .art-video-player .art-controls .art-control {
        min-width: 28px !important;
        min-height: 28px !important;
    }

    .art-video-player .art-controls .art-control .art-icon,
    .art-video-player .art-controls .art-control > svg {
        width: 20px !important;
        height: 20px !important;
        transform: scale(1) !important;
    }

    .art-video-player .art-controls .art-time {
        font-size: 11px !important;
        padding: 0 4px !important;
    }
}

@media (max-width: 480px) {
    .play-side .episode-btn {
        padding: 9px 2px;
        font-size: 12px;
    }
}

/* ========== 中等屏幕适配 ========== */
@media (max-width: 1080px) {
    .episode-grid {
        grid-template-columns: repeat(6, 1fr);
    }

    .play-info-header {
        padding: 14px 0 12px;       /* 横向归零：信息卡正文与播放器左缘对齐 */
    }

    .play-vod-name {
        font-size: 20px;
    }

    .play-info-nav {
        /*padding: 10px 16px;*/
    }

    .play-info-nav .play-nav-btn {
         /*padding: 10px 12px;*/
        font-size: 13px;
    }

    .play-episodes-section {
        padding: 16px;
        border-radius: 10px;
    }

    .episode-grid {
        grid-template-columns: repeat(4, 1fr);
        gap: 8px;
    }

    .episode-btn {
        font-size: 13px;
        padding: 10px 2px;
    }

    .source-tabs {
        gap: 12px;
        overflow-x: auto;
        padding-bottom: 8px;
        flex-wrap: nowrap;
        margin: 12px 0;
    }

    .source-tab {
        font-size: 14px;
        white-space: nowrap;
        flex-shrink: 0;
    }

    .vod-section-header {
        margin-bottom: 12px;
    }

    .vod-section-title {
        font-size: 17px;
    }
}

/* ========== 移动端响应式 ==========
   仅保留移动端独有、且未被上面 (max-width:1080px) 断点覆盖的规则。
   - 原第二份 768px 块里的 .episode-grid / .source-tabs / .play-episodes-section /
     .play-vod-name / .play-info-header 等与 1080px 断点逐条重复（1080 已覆盖 768），删除后表现不变；
   - 引用 .play-home-link / .play-topbar-title 的顶栏规则已废弃：移动端播放页整体隐藏 header，
     返回入口改由 .play-back-bar 承担（见上方第一个 768px 块）。 */
@media (max-width: 768px) {
    .play-info-card {
        margin-bottom: 16px;
    }

    .play-info-title-row {
        gap: 8px;
        margin-bottom: 6px;
    }

    .play-report-btn {
        padding: 4px 10px;
        font-size: 11px;
    }

    .play-info-meta {
        font-size: 12px;
    }
}

@media (max-width: 480px) {
    .episode-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .play-info-header {
        padding: 12px 0 10px;
    }

    .play-vod-name {
        font-size: 20px;
    }

    .play-info-nav {
        padding: 8px 14px;
        gap: 8px;
    }

    .play-info-nav .play-nav-btn {
        padding: 9px 8px;
        font-size: 12px;
        gap: 4px;
    }

    .play-episodes-section {
        padding: 14px;
    }

    .episode-btn {
        font-size: 12px;
        padding: 9px 2px;
    }
}

/* ========== 轻提示 Toast ========== */
.play-toast {
    position: fixed;
    top: 90px;
    left: 50%;
    transform: translate(-50%, -16px);
    z-index: 10000;
    max-width: calc(100% - 40px);
    padding: 12px 22px;
    font-size: 14px;
    line-height: 1.5;
    color: #fff;
    text-align: center;
    border-radius: 24px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.play-toast.show {
    opacity: 1;
    transform: translate(-50%, 0);
}

.play-toast-success {
    background: linear-gradient(135deg, #43a047, #2e7d32);
}

.play-toast-error {
    background: linear-gradient(135deg, #e53935, #c62828);
}

/*
 * Toast 落点：PC 端仍是 90px（躲开固定导航栏），移动端播放页抬到单行顶栏下方。
 */
@media (max-width: 768px) {
    .play-meta-ep {
        font-size: 20px;
    }

    .play-toast {
        top: 100px;
        font-size: 13px;
        padding: 10px 18px;
    }

    /* 特异性 (0,2,1) 压得住同一个媒体查询里的 .play-toast (0,1,0) */
    body.is-play-page .play-toast {
        top: 56px;
    }
}
