/**
 * 內容模塊（前台）
 *
 * ⚠️ 手機斷點 767px 必須與 config/content_blocks.php 的 mobile_breakpoint 一致。
 *    <picture> 的 media query 由該設定產生，兩邊不同步會出現
 *    「圖已切手機版、版面還是桌機版」的錯位。
 *    ContentBlocksAssetTest 有測試釘住這件事，改這裡請一併改設定檔。
 *
 * 命名全部 cb- 前綴，避免與前台既有樣式（all.css）衝突。
 */

/* ── 共用 ────────────────────────────────────────────────── */

.cb-blocks { width: 100%; }

/*
 * 重置 margin / padding 是必要的，不是保險起見：
 * 前台的 all.css 有針對元素的全域規則（實測 `section` 被套上 padding:100px 0），
 * 而所有模塊都用 <section>。不重置的話，沒有自訂 padding 的模塊（例如滿版圖）
 * 會平白多出上下各 100px 的白邊。
 *
 * 各模塊在下方各自宣告自己要的 padding；class 選擇器特異性相同，
 * 但宣告在後面所以會覆蓋這裡的 0。
 */
.cb-block {
    background: var(--cb-bg, transparent);
    position: relative;
    margin: 0;
    padding: 0;
}

/*
 * 全站無寬度上限（2026-08-23 客戶決議）。
 *
 * 原本 `.cb-blocks > *` 統一壓在 1520px，只有滿版圖與滿版輪播例外。現在反過來：
 * 預設貼齊瀏覽器邊緣，桌機與手機都是 0 內距，只有「不滿版圖」自己限寬——
 * 那正是它的用途。
 *
 * 也因為沒有固定的容器寬度可以參照，所有版面數值才一併從 px 改成 %：
 * 同樣的 400px 在 1280 與 2560 的螢幕上是完全不同的視覺比例。
 *
 * 這裡刻意「不」寫 max-width，連 none 都不寫——沒有規則就沒有要同步的值。
 */
.cb-blocks > * { width: 100%; }

/*
 * 模塊之間的間隔。
 *
 * 統一由這一條控制，各模塊本身「不再」自帶上下留白——原本每個模塊各自定義
 * （滿版圖 0、線上編輯器 24px、文字與圖文 40px），導致實際間距取決於相鄰的是
 * 哪兩種模塊：線上編輯器接滿版圖只有 24px，看起來就是黏在一起。
 *
 * 例外：連續的滿版圖維持無縫堆疊。舊彩頁的 144 筆商品全部是「一疊切片圖」，
 * 那些圖是當成一張完整設計切開的，中間一旦有縫就會斷開。
 */
.cb-blocks > * + * { margin-top: var(--cb-block-gap, 48px); }
.cb-blocks > .cb-full-image + .cb-full-image { margin-top: 0; }

/* 整個模塊區與頁面其他內容之間也要留白 */
.cb-blocks { padding-top: 40px; padding-bottom: 40px; }

.cb-pic { display: block; }
.cb-pic img {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
}

.cb-align-left   { text-align: left; }
.cb-align-center { text-align: center; }
.cb-align-right  { text-align: right; }

/* ── 1. 滿版圖 ───────────────────────────────────────────── */
.cb-full-image { line-height: 0; }
.cb-full-image__link { display: block; }

/* ── 7. 不滿版圖 ─────────────────────────────────────────── */
/* 唯一仍然限寬的模塊。寬度由 --cb-max-w 帶入，單位 %（佔瀏覽器寬度） */
.cb-boxed-image { padding: 0; }
.cb-boxed-image__inner {
    max-width: var(--cb-max-w, 63%);
    line-height: 0;
}
.cb-align-center .cb-boxed-image__inner { margin: 0 auto; }
.cb-align-right  .cb-boxed-image__inner { margin-left: auto; }

/* ── 文字（2 / 3 / 4 共用） ──────────────────────────────── */
/*
 * 間距與行距由 --cb-gap-* 帶入，桌機手機各一組，單位 %。
 *
 * 「描述的行距」是 line-height：文字折行後每一行之間的距離。
 * 客戶說的「段落間距」實際指的是這個，不是段落與段落之間。
 *
 * ⚠️ 兩者的百分比基準不同，這是 CSS 規範定死的：
 *      margin 的 %      → 相對「容器寬度」
 *      line-height 的 % → 相對「字級」
 *    所以 0.6% 的間距與 180% 的行距不是同一個尺度。後台每一欄都會標明基準。
 */
.cb-text__title {
    font-size: var(--cb-title-pc, 32px);
    color: var(--cb-title-c, #333);
    margin: 0 0 var(--cb-gap-title-subtitle-pc, 0.6%);
    line-height: 1.35;
}
.cb-text__subtitle {
    font-size: var(--cb-subtitle-pc, 20px);
    color: var(--cb-subtitle-c, #666);
    margin: 0 0 var(--cb-gap-subtitle-content-pc, 0.6%);
    line-height: 1.5;
}
.cb-text__content {
    font-size: var(--cb-content-pc, 16px);
    color: var(--cb-content-c, #666);
    line-height: var(--cb-gap-content-line-pc, 180%);
}

/* 主標後面直接接描述（沒有副標）時，用副標↔描述那組間距 */
.cb-text__title + .cb-text__content { margin-top: 0; }
.cb-text:not(:has(.cb-text__subtitle)) .cb-text__title {
    margin-bottom: var(--cb-gap-subtitle-content-pc, 0.6%);
}
.cb-text__btn {
    display: inline-block;
    margin-top: 18px;
    padding: 10px 28px;
    border-radius: 4px;
    background: #0d6efd;
    color: #fff;
    text-decoration: none;
    font-size: 15px;
    transition: opacity .2s;
}
.cb-text__btn:hover { opacity: .85; color: #fff; text-decoration: none; }

/* ── 4. 文字模塊 ─────────────────────────────────────────── */
/* 貼齊瀏覽器邊緣：置左就要真的在最左邊，置右就要真的在最右邊（客戶指定） */
.cb-text-block { padding: 0; }
.cb-text-block__inner { max-width: none; }

/* ── 2 / 3. 左圖右文、左文右圖 ───────────────────────────── */
/*
 * 三欄連動：圖片寬 + 間距 + 文字寬，三者都是佔模塊寬度的百分比，合計 ≤ 100%。
 *
 * 舊版只有一個「圖片佔比」，文字自動吃掉剩下的——那樣表達不了「中間要留多少
 * 間距」，而客戶要能分別控制三段。改成三個獨立的值後，gap 也是 % 而不是固定
 * px，才能跟另外兩欄湊成同一條 100% 的分配。
 *
 * 總和小於 100 時右側留白，是合理的版面選擇，不做補滿。
 */
.cb-split {
    display: flex;
    align-items: center;
    gap: var(--cb-split-gap, 4%);
    padding: 0;
}
.cb-split__media { flex: 0 0 var(--cb-img-w, 48%);  min-width: 0; line-height: 0; }
.cb-split__body  { flex: 0 0 var(--cb-text-w, 48%); min-width: 0; }

/* 左文右圖：markup 順序不變，只把媒體排到後面 */
.cb-split--text-first .cb-split__media { order: 2; }
.cb-split--text-first .cb-split__body  { order: 1; }

/* ── 5. 線上編輯器 ───────────────────────────────────────── */
.cb-rich-text { padding: 0; }

/*
 * display: flow-root 是必要的，不是保險起見。
 *
 * 舊 CKEditor 產出的內容大量使用 <img style="float: left; width: 100%">
 * （改版前的商品彩頁 100% 是這個 pattern）。浮動元素不會撐開父層，因此
 * 容器高度會塌成 0，圖片整個溢出去壓在下一個模塊上面——實測某個分類頁的
 * 線上編輯器區塊只有 66px 高，裡面卻有一張 664px 的圖。
 *
 * flow-root 會建立獨立的區塊格式化脈絡，把浮動內容包回容器內，
 * 同時也避免子元素的 margin 穿透出去。::after 是給不支援 flow-root 的
 * 舊瀏覽器的退路，兩者並存不衝突。
 */
.cb-rich-text__pc,
.cb-rich-text__mobile {
    display: flow-root;
    max-width: none;
}
.cb-rich-text__pc::after,
.cb-rich-text__mobile::after {
    content: '';
    display: table;
    clear: both;
}
.cb-rich-text__pc img,
.cb-rich-text__mobile img { max-width: 100%; height: auto; }
.cb-rich-text__mobile { display: none; }

/*
 * 還原編輯器產出的基本排版。
 *
 * 前台的 all.css 把 ul/ol 的 list-style 與 padding 清成 0（給導覽列用的 reset），
 * 導致編輯者在 CKEditor 打的項目清單，到前台變成沒有符號的一排文字。
 * 這裡把清單、表格、引言的預設樣式在模塊範圍內補回來——只影響 .cb-rich-text 內，
 * 不動到站上其他地方。
 */
.cb-rich-text ul,
.cb-rich-text ol { padding-left: 1.6em; margin: 0 0 1em; }
.cb-rich-text ul { list-style: disc; }
.cb-rich-text ol { list-style: decimal; }
.cb-rich-text li { margin-bottom: .4em; list-style: inherit; }

.cb-rich-text p { margin: 0 0 1em; line-height: 1.8; }
.cb-rich-text h1,
.cb-rich-text h2,
.cb-rich-text h3,
.cb-rich-text h4 { margin: 1.2em 0 .6em; line-height: 1.4; }
.cb-rich-text a { text-decoration: underline; }

.cb-rich-text table { width: 100%; border-collapse: collapse; margin: 0 0 1em; }
.cb-rich-text th,
.cb-rich-text td { border: 1px solid #ddd; padding: 8px 10px; }

.cb-rich-text blockquote {
    margin: 0 0 1em;
    padding: 8px 16px;
    border-left: 3px solid #ddd;
    color: #666;
}

/* ── 6. 輪播 ─────────────────────────────────────────────── */
.cb-carousel { padding: 0; overflow: hidden; }
.cb-carousel__title {
    text-align: center;
    margin: 0 0 24px;
    font-size: 26px;
    color: #333;
}
.cb-carousel__swiper { padding: 10px 0 44px; }
.cb-carousel__slide {
    width: 60%;
    max-width: 720px;
    line-height: 0;
}
.cb-carousel__slide img { border-radius: 6px; }

/*
 * 圓點容器的基本定位。
 *
 * 同上：換掉 swiper-pagination 這個公用 class 之後，all.css 給的
 * position: absolute 也跟著失效，圓點會掉回文件流。滿版模式在下方另有覆蓋，
 * 這裡是所有效果共用的底。
 */
.cb-carousel__pagination {
    position: absolute;
    bottom: 12px;
    left: 0;
    width: 100%;
    text-align: center;
    z-index: 2;
}
.cb-carousel__caption {
    line-height: 1.5;
    margin: 10px 0 0;
    text-align: center;
    font-size: 14px;
    color: #666;
}

/* ── 8. 影音（R10：主播放器 + 右側播放清單） ─────────────── */
.cb-video { padding: 0; }
.cb-video__title { text-align: center; margin: 0 0 24px; font-size: 26px; color: #333; }

/*
 * 桌機：左右分欄，兩者同高（對標參考站）。
 * 三欄連動：播放區 + 間距 + 清單，三者都是佔模塊寬度的百分比，合計 ≤ 100%。
 *
 * 用 grid 而不是 flex：欄寬要精確等於設定的百分比，flex 的 basis 還會被
 * flex-shrink 動到。grid 的 gap 與欄寬同樣以容器寬度為基準，三者才湊得成
 * 同一條 100%。
 *
 * 主播放器「限寬不限高」——寬度由設定帶入，高度靠 aspect-ratio 自動算出，
 * 因此前台長寬永遠等比，不會因為設定而變形。
 */
.cb-video__wrap {
    display: grid;
    grid-template-columns: var(--cb-player-w, 66%) var(--cb-list-w, 33%);
    gap: var(--cb-list-gap, 1%);
    align-items: stretch;
}

.cb-video__player { min-width: 0; }
.cb-video.is-single .cb-video__wrap { grid-template-columns: var(--cb-player-w, 66%); }

/*
 * 播放清單：高度等於主播放器，超出的項目在清單內捲動。
 *
 * height: 0 + min-height: 100% 是必要的組合，不是繞路：
 *   - 欄寬改成 % 之後，原本的 calc(播放器寬 × 9/16) 失效——CSS 的百分比高度
 *     是相對「父層高度」而非寬度，calc(66% * 9/16) 會算出完全無關的值。
 *   - 直接讓它 stretch 的話，清單項目一多就會反過來把整列撐高，播放器下方
 *     多出一段空白。height: 0 讓它不參與列高計算（列高由播放器決定），
 *     min-height: 100% 再把它撐回與播放器同高。
 */
.cb-video__playlist {
    min-width: 0;
    height: 0;
    min-height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    border: 1px solid #e6e9ef;
    border-radius: 6px;
    background: #fafbfc;
}
.cb-video__playlist::-webkit-scrollbar { width: 8px; }
.cb-video__playlist::-webkit-scrollbar-thumb { background: #c6ccd8; border-radius: 4px; }
.cb-video__playlist::-webkit-scrollbar-track { background: transparent; }

.cb-video__entry {
    display: flex;
    gap: 10px;
    width: 100%;
    padding: 10px;
    border: 0;
    border-bottom: 1px solid #eef1f6;
    background: transparent;
    text-align: left;
    cursor: pointer;
    transition: background .15s;
}
.cb-video__entry:last-child { border-bottom: 0; }
.cb-video__entry:hover { background: #eef3fb; }
.cb-video__entry.is-active { background: #e3edfb; }

.cb-video__entry-thumb {
    flex: 0 0 140px;
    align-self: flex-start;
    aspect-ratio: 16 / 9;
    border-radius: 4px;
    overflow: hidden;
    background: #000;
}
.cb-video__entry-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.cb-video__entry-meta { flex: 1 1 auto; min-width: 0; }
.cb-video__entry-title {
    display: block;
    font-size: 14px;
    line-height: 1.45;
    color: #333;
    /* 標題最多兩行，避免長標題把清單項目撐得高矮不一 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/*
 * 清單內的描述限制兩行：不設限的話，長描述會把每個項目撐得很高，
 * 可見筆數從約 4~5 筆掉到 1~2 筆，清單就失去快速瀏覽的作用。
 * 完整描述在下方說明區，切換影片時會跟著換。
 */
.cb-video__entry-desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 4px;
    font-size: 12.5px;
    line-height: 1.5;
    color: #7b8391;
}

.cb-video__entry-duration { display: block; margin-top: 4px; font-size: 12px; color: #8b97aa; }

/* 主播放器的縮圖與 iframe：aspect-ratio 讓兩者高度一致，切換時不會跳動 */
.cb-video__thumb {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: #000;
    border-radius: 6px;
    overflow: hidden;
    cursor: pointer;
    aspect-ratio: 16 / 9;
}
.cb-video__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .3s, opacity .3s;
}
.cb-video__thumb:hover img { transform: scale(1.03); opacity: .85; }

/* 播放鍵用純 CSS 畫，不額外要一張圖 */
.cb-video__play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 68px;
    height: 48px;
    background: rgba(0, 0, 0, .7);
    border-radius: 10px;
    transition: background .2s;
}
.cb-video__play::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-40%, -50%);
    border-style: solid;
    border-width: 10px 0 10px 17px;
    border-color: transparent transparent transparent #fff;
}
.cb-video__thumb:hover .cb-video__play { background: #ff0000; }

.cb-video__frame {
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
    border-radius: 6px;
    display: block;
}

/* ── 手機（767px 必須與 config 的 mobile_breakpoint 同步）─── */
@media (max-width: 767px) {
    /* 手機螢幕窄，間距同比例縮小 */
    .cb-blocks > * + * { margin-top: var(--cb-block-gap-mb, 32px); }
    .cb-blocks { padding-top: 24px; padding-bottom: 24px; }

    .cb-text__title {
        font-size: var(--cb-title-mb, 22px);
        margin-bottom: var(--cb-gap-title-subtitle-mb, 2.1%);
    }
    .cb-text__subtitle {
        font-size: var(--cb-subtitle-mb, 16px);
        margin-bottom: var(--cb-gap-subtitle-content-mb, 2.1%);
    }
    .cb-text__content {
        font-size: var(--cb-content-mb, 14px);
        line-height: var(--cb-gap-content-line-mb, 180%);
    }
    .cb-text:not(:has(.cb-text__subtitle)) .cb-text__title {
        margin-bottom: var(--cb-gap-subtitle-content-mb, 2.1%);
    }

    .cb-boxed-image__inner { max-width: 100%; }   /* 手機不限寬，本來就窄 */

    /* 手機同樣 0 內距（客戶指定「全部完全貼邊」） */
    .cb-split {
        flex-direction: column;
        gap: var(--cb-split-gap-mb, 20px);
        padding: 0;
    }
    .cb-split__media,
    .cb-split__body { flex: 0 0 auto; width: 100%; }   /* 手機單欄，忽略桌機比例 */

    /* 手機堆疊順序：預設圖片在上，可改為文字在上 */
    .cb-split .cb-split__media { order: 1; }
    .cb-split .cb-split__body  { order: 2; }
    .cb-mobile-text_first .cb-split__media { order: 2; }
    .cb-mobile-text_first .cb-split__body  { order: 1; }

    /* 手機版內容有填時取代桌機版；沒填則桌機那份照常顯示 */
    .cb-rich-text.has-mobile .cb-rich-text__pc { display: none; }
    .cb-rich-text.has-mobile .cb-rich-text__mobile { display: block; }

    .cb-carousel { padding: 0; }
    .cb-carousel__title,
    .cb-video__title { font-size: 20px; margin-bottom: 16px; }
    .cb-carousel__slide { width: 84%; }

    /* 手機：主播放器在上、播放清單在下，清單維持固定高度並可捲動（客戶指定）。
       單欄堆疊，桌機的三欄百分比在此不適用。 */
    .cb-video__wrap,
    .cb-video.is-single .cb-video__wrap {
        grid-template-columns: 100%;
        gap: 12px;
    }
    .cb-video__playlist {
        height: 260px;
        min-height: 0;
    }
    .cb-video__entry-thumb { flex-basis: 110px; }
}

/*
 * 輪播效果（R6）
 *
 * 預設的 .cb-carousel__slide 寬度 60% 是給 coverflow 用的——側邊要露出
 * 才看得到 3D 層疊。其餘效果都是單張呈現，必須吃滿整個容器寬度，
 * 否則會變成一張小圖浮在中間。
 */
.cb-carousel--fade .cb-carousel__slide,
.cb-carousel--cube .cb-carousel__slide,
.cb-carousel--flip .cb-carousel__slide {
    width: 100%;
    max-width: none;
}

/* 平移的滿版模式：對齊 akuvox 首頁，一張圖佔滿整個寬度、左右不留白 */
/* 滿版輪播的上下留白已由 .cb-blocks > * + * 統一控制 */
.cb-carousel.is-full .cb-carousel__swiper { padding: 0; }
.cb-carousel.is-full .cb-carousel__slide {
    width: 100%;
    max-width: none;
}

/*
 * coverflow 是例外：滿版之後仍要露出左右鄰片（客戶指定），否則 3D 層疊就
 * 看不出來，跟平移沒有差別。單張寬度取瀏覽器寬度的 60%，兩側各露出 20%。
 * flip / cube 沒有這個需求——它們的動畫發生在單張自己身上。
 */
.cb-carousel--coverflow.is-full .cb-carousel__slide {
    width: 60%;
    max-width: none;
}
.cb-carousel.is-full .cb-carousel__slide img { border-radius: 0; }
/* 必須寫在上一條之後：兩者特異性相同，靠順序決勝負 */
.cb-carousel--coverflow.is-full .cb-carousel__slide img { border-radius: 6px; }
.cb-carousel.is-full .cb-carousel__title { padding-top: 0; }

/*
 * 圖片底部的漸層遮罩。
 *
 * 這不是裝飾，是圓點與說明文字能被看見的前提。akuvox 的白色空心圓點看得
 * 清楚，是因為它的輪播圖底部本來就是深色；但這裡的圖片由使用者自行上傳，
 * 底部是白色的機率很高，白圓點疊上去就等於消失（客戶回報「看不到圓點」的
 * 主因之一）。
 *
 * 用漸層而不是替圓點加深色底，是因為說明文字也在同一區，整片壓暗比逐個
 * 元件加陰影乾淨，而且深色圖上幾乎看不出遮罩的存在。
 */
.cb-carousel.is-full .cb-carousel__slide { position: relative; }
.cb-carousel.is-full .cb-carousel__slide::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 180px;
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.42) 100%);
    pointer-events: none;
    z-index: 1;
}

/*
 * 滿版時說明文字改為疊在圖片上。
 *
 * 留在流程內的話，圖片下方會多出一截文字高度，靠 bottom 定位的圓點就會被
 * 擠到圖片外面（客戶回報「看不到圓點」的另一個成因）。
 */
.cb-carousel.is-full .cb-carousel__caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 88px;
    margin: 0;
    padding: 0 60px;
    z-index: 2;
    color: #fff;
    font-size: 16px;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/*
 * 滿版輪播的分頁圓點：疊在圖片之上（對齊 akuvox 首頁，以下數值皆為實測值）
 *
 *   位置    absolute，距底 56px，滿寬置中
 *   圓點    15x15、透明底、1px 白色外框、圓形、左右各 4px
 *   作用中  同樣式 + scale(1.5)，不改顏色
 *
 * 圓點維持 akuvox 的空心白框；能不能看見交給上面的漸層遮罩負責。
 */
.cb-carousel.is-full .cb-carousel__pagination {
    position: absolute;
    bottom: 56px;
    left: 0;
    width: 100%;
    text-align: center;
    line-height: 0;
    z-index: 2;
}

.cb-carousel.is-full .cb-carousel__pagination .swiper-pagination-bullet {
    width: 15px;
    height: 15px;
    margin: 0 4px;
    background: transparent;
    border: 1px solid #fff;
    border-radius: 100%;
    opacity: 1;
    /* Swiper 舊版的 bullet 預設是實心深色，這裡整組覆蓋掉 */

    /*
     * 刻意「不」在 transform 上加 transition。
     *
     * 實測加了之後會出現嚴重的殘留：切走的那顆永遠停在放大狀態，新選中的
     * 那顆卻沒放大，連 getComputedStyle 回報的值都與實際命中的規則對不起來
     * （強制重繪才會修正）。這個環境的 Swiper 版本在切換 bullet class 時
     * 會踩到瀏覽器的 transform 合成快取。
     *
     * akuvox 本身也沒有轉場，圓點是直接切換大小，因此拿掉反而更貼近參考站。
     */
    transform: scale(1);
}

.cb-carousel.is-full .cb-carousel__pagination .swiper-pagination-bullet-active {
    background: transparent;
    border-color: #fff;
    transform: scale(1.5);
}

@media (max-width: 767px) {
    /* 手機畫面較矮，圓點往下靠 */
    .cb-carousel.is-full .cb-carousel__pagination { bottom: 20px; }
    .cb-carousel.is-full .cb-carousel__caption { bottom: 48px; padding: 0 24px; font-size: 14px; }
    .cb-carousel.is-full .cb-carousel__slide::after { height: 120px; }
}

/*
 * 左右箭頭
 * ---------
 * 箭頭的圖示必須自己畫。這個站的 Swiper 是包在 plugin-min.js 裡的舊版，
 * 只有 JS 沒有附帶官方樣式，而站台 all.css 只定義了 .swiper-button-prev/next
 * 的定位，沒有給圖示——實測 background-image 是 none、::after 的 content 是
 * 空字串，等於一個 27x44 的透明空盒子。這就是客戶「明明啟用了箭頭卻看不到」
 * 的原因：元素一直都在，只是沒有任何東西被畫出來。
 *
 * 圖示用 border 轉 45 度畫（不靠字型或 SVG 檔），少一個外部相依。
 *
 * 位置也必須改：舊值是 left/right: -5px，而 .cb-carousel 是 overflow: hidden，
 * 箭頭有一部分被容器裁掉。
 *
 * class 名稱刻意不用 swiper-button-prev/next
 * ------------------------------------------
 * 站台有 7 處以字串選擇器初始化 Swiper 的導覽（另有 3 處這樣抓 .swiper-pagination），
 * 例如商品比較列的 new Swiper('.siwperCompare', { navigation: { nextEl: '.swiper-button-next' } })。
 * Swiper 是用 document 範圍去找的，當那個容器裡沒有自己的箭頭時，就會把頁面上
 * 所有同名元素一併接管——實測我們的箭頭因此被蓋上 swiper-button-disabled
 * （opacity: .35、pointer-events: none），在淺色圖上等於消失，也點不動。
 * 換成專屬 class 後別人抓不到，我們的 JS 則是直接傳元素進去。
 */
/*
 * 定位必須自己寫齊。
 *
 * 換掉公用 class 之後，all.css 提供的 position: absolute / cursor 也一併失效，
 * 箭頭會掉回文件流、疊在輪播下方（實測整個區塊塌成 99px 高）。這裡不再假設
 * 任何外部樣式存在，需要的屬性全部列出來。
 */
.cb-carousel .cb-carousel__nav--prev,
.cb-carousel .cb-carousel__nav--next {
    position: absolute;
    top: 50%;
    margin-top: -22px;
    width: 44px;
    height: 44px;
    cursor: pointer;
    user-select: none;
    background-image: none;
    background-color: rgba(0, 0, 0, 0.32);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.2s ease;
    z-index: 10;
}
.cb-carousel .cb-carousel__nav--prev { left: 24px; right: auto; }
.cb-carousel .cb-carousel__nav--next { right: 24px; left: auto; }

.cb-carousel .cb-carousel__nav--prev:hover,
.cb-carousel .cb-carousel__nav--next:hover { background-color: rgba(0, 0, 0, 0.55); }

.cb-carousel .cb-carousel__nav--prev::after,
.cb-carousel .cb-carousel__nav--next::after {
    content: '';
    display: block;
    width: 12px;
    height: 12px;
    border: 2px solid #fff;
    /* 只留兩邊，旋轉後就是 V 形箭頭 */
    border-left: 0;
    border-bottom: 0;
    font-size: 0;
}
.cb-carousel .cb-carousel__nav--prev::after {
    transform: rotate(-135deg);
    /* 補回旋轉後視覺重心的偏移，讓箭頭看起來在圓心 */
    margin-left: 4px;
}
.cb-carousel .cb-carousel__nav--next::after {
    transform: rotate(45deg);
    margin-right: 4px;
}

@media (max-width: 767px) {
    .cb-carousel .cb-carousel__nav--prev,
    .cb-carousel .cb-carousel__nav--next { width: 36px; height: 36px; margin-top: -18px; }
    .cb-carousel .cb-carousel__nav--prev { left: 10px; }
    .cb-carousel .cb-carousel__nav--next { right: 10px; }
    .cb-carousel .cb-carousel__nav--prev::after,
    .cb-carousel .cb-carousel__nav--next::after { width: 10px; height: 10px; }
}

/* cube / flip 需要固定高度才不會在切換時抖動 */
.cb-carousel--cube .cb-carousel__swiper,
.cb-carousel--flip .cb-carousel__swiper { overflow: visible; }

/* 影音說明區：顯示目前播放影片的標題、時長與描述 */
.cb-video__intro {
    max-width: min(
        calc(var(--cb-player-w, 1000px) + var(--cb-list-w, 400px) + var(--cb-list-gap, 16px)),
        1520px
    );
    margin: 20px auto 0;
}
.cb-video__intro-title {
    display: inline;
    margin: 0;
    font-size: 20px;
    line-height: 1.5;
    color: #333;
}
.cb-video__intro-duration {
    display: inline-block;
    margin-left: 10px;
    padding: 1px 8px;
    border-radius: 3px;
    background: #eef2f8;
    color: #6b7891;
    font-size: 13px;
    vertical-align: middle;
}
.cb-video__intro-desc {
    margin: 10px 0 0;
    font-size: 15px;
    line-height: 1.8;
    color: #666;
    white-space: pre-line;   /* 保留編輯者輸入的換行 */
}
.cb-video__intro-title[hidden],
.cb-video__intro-duration[hidden],
.cb-video__intro-desc[hidden] { display: none; }
