/* Chaovisual Gallery — 作品影像（chaovisual/frame）

   這個區塊的前提是「它會獨佔一整個螢幕」。所有的尺寸都從視窗高度算，
   不是從內容算——反過來的話，直式照片會把頁面撐得比視窗還高，
   跨頁式的吸附就會被那一頁擋住。

   --cvf-room 是這一頁除了照片以外的東西佔掉的高度：說明文字、
   頁面本身的上下留白。它由主題的 .sw-page 決定（那裡才知道有沒有文字），
   這裡只給一個在一般頁面上也說得通的預設。 */

.cvf {
  --cvf-room: 150px;
  margin: 0 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(12px, 1.6vh, 20px);
}

/* 舞台用 flex，而且 width:fit-content。

   本來是 grid + 圖片 width:100%：格子撐滿欄寬，照片靠 object-fit:contain
   在裡面置中留黑。畫面上看起來是對的，但那個「格子」比照片大得多——
   1400px 的欄位裡放一張 3:4 的直式照片，照片只有 547px 寬，
   其餘 853px 是可以點、游標會變成 zoom-in、但什麼都沒有的空白。
   壓在角落的說明文字也是貼到那個空盒子的角，不是照片的角。

   改成「盒子貼著照片」：寬度由高度上限反推（width:auto + max-height），
   舞台再 fit-content 收起來、margin-inline:auto 置中。
   這跟主題在跨頁式裡處理圖片的原則是同一個，一頁兩張也是這樣做的。 */
.cvf-stage {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: clamp(10px, 1.6vw, 22px);
  position: relative;
}

.cvf-cell { position: relative; min-width: 0; flex: 0 1 auto; display: flex; }

.cvf-img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: calc(100svh - var(--cvf-room));
  object-fit: contain;
  border-radius: var(--r-img, 3px);
}

/* ---- 三種呈現 ---- */

/* 完整顯示：整張照片都看得到，寧可上下留黑。
   這是預設，理由跟跨頁式當初選 object-fit:contain 一樣——
   為了填滿畫面而把構圖切掉，等於把這個版面存在的理由拿掉。 */
.cvf-fit-contain .cvf-img { object-fit: contain; }

/* 滿版出血：照片鋪滿整個螢幕，左右不留邊。
   只有在照片本身經得起被裁的時候才該用（風景、質感特寫）。
   焦點由每張圖自己的 object-position 決定。

   ---- 1.18.1：只在電腦視窗全展開時才成立 ----

   整段包在 min-width:1200px 裡面，理由是「滿版出血」這個選擇的前提是
   **有足夠的寬度可以裁**。視窗一窄，同一張橫幅照片被切成直的，
   構圖裡真正的主體常常整個不見——那不是「滿版」，是「裁壞」。

   實作上刻意用「整段包起來」而不是「在小螢幕再寫一組規則覆蓋回去」：
   覆蓋回去要逐條解掉 --cvf-room、width、margin-inline、object-fit、
   border-radius、filter⋯⋯漏掉任何一條就會留下一個只在某個寬度出現的
   怪版面，而那種 bug 很難被發現。包起來的話，1200px 以下這裡完全不生效，
   照片自動落回檔案最上面那組基準規則——也就是「完整顯示」。

   1200 是主題既有的斷點之一。要改門檻就改這一行（與下面 .cvf-ar 那一段）。 */
@media (min-width: 1200px) {
  .cvf-fit-cover { --cvf-room: 0px; width: 100vw; margin-inline: calc(50% - 50vw); }
  /* 滿版時盒子就是螢幕，不需要（也不能）貼著照片收起來。 */
  .cvf-fit-cover .cvf-stage { gap: 0; width: 100%; }
  .cvf-fit-cover .cvf-cell { flex: 1 1 0; }
  .cvf-fit-cover .cvf-img {
    width: 100%;
    max-width: none;
    height: 100svh;
    max-height: none;
    object-fit: cover;
    border-radius: 0;
  }
}

/* 置中留白：照片縮到八成，四周留出更多空氣。
   同一組作品裡穿插一兩張這種頁面，節奏會鬆下來。 */
.cvf-fit-inset .cvf-img { max-height: calc((100svh - var(--cvf-room)) * 0.82); }
.cvf-fit-inset .cvf-stage { max-width: 82%; margin-inline: auto; }

/* ---- 兩張：對照 ----
   兩張的時候舞台改回撐滿：每一格要有一個「一半」可以算，
   而 fit-content 的一半是循環定義（寬度取決於內容、內容又取決於寬度）。
   兩張並排時壓在角落的說明會貼到這一對的角，不是單張照片的角——
   那是對的，說明講的是這一對。 */
.cvf-two .cvf-stage { width: 100%; }
.cvf-two.cvf-pair-side .cvf-cell {
  max-width: calc(50% - clamp(10px, 1.6vw, 22px) / 2);
  justify-content: center;
}

/* ---- 兩張並排：不同比例也同高（1.18.3） ----

   上面那條把兩格切成各一半，於是一張 2:3、一張 3:4 各自維持原比例時
   高度不一樣、底線對不齊——畫面上看起來像沒對好，而讀者第一眼看到的
   會是那個不齊，不是那兩張照片的關係。

   解法不是「切一半」而是「按比例分」：flex-basis 設 0、flex-grow 等於
   **那一張自己的長寬比**（由 PHP 從附件尺寸算好寫進 --cvf-cell-ar）。
   於是每一格的寬度正比於自己的比例，而「寬度 ÷ 比例 ＝ 高度」
   對兩格算出同一個值——兩張自然同高，寬度各自不同。這是 justified 排版
   的標準做法，只是那個比例 CSS 自己看不到，得由 PHP 告訴它。

   高度上限反過來由寬度限制：高度 ＝（容器寬 − 間距）÷ 比例總和，
   所以容器最寬只能是「高度預算 × 比例總和 ＋ 間距」。

   指定了長寬比時整段不生效（:not(.cvf-ar)）——那時兩格本來就同一個形狀。 */
.cvf-two.cvf-pair-side:not(.cvf-ar) .cvf-stage {
  align-items: flex-start;
  max-width: calc(
    (100svh - var(--cvf-room)) * var(--cvf-ar-sum, 2) + clamp(10px, 1.6vw, 22px)
  );
}
.cvf-two.cvf-pair-side:not(.cvf-ar) .cvf-cell {
  flex: var(--cvf-cell-ar, 1) 1 0;
  max-width: none;
}
.cvf-two.cvf-pair-side:not(.cvf-ar) .cvf-img {
  width: 100%;
  height: auto;
  max-width: none;
  max-height: none;
}
.cvf-two.cvf-pair-stack .cvf-stage { flex-direction: column; }
/* 上下排時每一張各分一半的高度預算，否則兩張都用滿高會超出視窗。 */
.cvf-two.cvf-pair-stack .cvf-img { max-height: calc((100svh - var(--cvf-room)) / 2 - 12px); }
@media (max-width: 700px) {
  /* 手機上兩張並排，每一張只剩半個螢幕寬——那不是對照，是兩張縮圖。
     一律改成上下排。 */
  .cvf-two .cvf-stage { flex-direction: column; }
  .cvf-two.cvf-pair-side .cvf-cell { max-width: 100%; }
  .cvf-two .cvf-img { max-height: calc((100svh - var(--cvf-room)) / 2 - 12px); }
}

/* ---- 指定長寬比（1.18.0） ----

   auto（原始比例）時這一整段都不會生效——沒有 .cvf-ar 就沒有這些規則，
   照片維持它自己的形狀，也就是這個區塊本來的行為。

   兩條 calc() 是一組的：
     aspect-ratio 決定格子的形狀，
     max-width 決定它在高度用完之前先把寬度收起來。
   少了第二條，2:3 這種直式比例會把頁面撐得比視窗還高，
   跨頁式的吸附就會被那一頁擋住——那正是這個區塊最初要避開的問題。
   「* var(--cvf-ar)」看起來像在乘一個分數，實際上 calc() 會把
   「* 2/3」當成先乘後除，結果就是「高度預算換算成寬度」。 */
.cvf-ar .cvf-stage { width: 100%; }
.cvf-ar .cvf-cell {
  width: 100%;
  aspect-ratio: var(--cvf-ar);
  max-width: calc((100svh - var(--cvf-room)) * var(--cvf-ar));
  margin-inline: auto;
}
/* 指定比例＝裁切，不是留白（1.18.2）。
   一開始這裡讓填滿方式跟著「版面」走，於是「完整顯示＋4:5」會變成
   一張照片在 4:5 的框裡上下留黑——那等於什麼都沒發生，框是空的、
   照片還是原來的形狀。指定比例的意思本來就是「我要這個形狀」，
   所以一律 cover：**照片被裁到那個比例，露出哪一塊由焦點決定。**
   焦點因此不再只屬於滿版出血，有比例的時候也一定有焦點可調。 */
.cvf-ar .cvf-img {
  width: 100%; height: 100%;
  max-width: none; max-height: none;
  object-fit: cover;
}

/* 滿版出血 ＋ 指定比例＝整個螢幕寬的橫幅，高度由比例決定。
   這是 21:9 真正好用的地方：建築的水平線在一條窄帶裡比在整個螢幕裡
   更清楚——整個螢幕高會讓視線上下游移，窄帶會逼它左右走。

   同樣只在視窗全展開時成立。1200px 以下會落回上面那組 .cvf-ar 規則：
   **比例的框留著，照片改成在框裡置中留白**——形狀不變、不再裁切，
   一排照片的節奏因此在手機上也還是對齊的。 */
@media (min-width: 1200px) {
  .cvf-fit-cover.cvf-ar .cvf-cell {
    max-width: none;
    height: auto;
    aspect-ratio: var(--cvf-ar);
  }
  .cvf-fit-cover.cvf-ar .cvf-img { height: 100%; border-radius: 0; }
}
/* 窄視窗：滿版失效、比例框留著，照片仍然是裁切的——
   形狀不變、焦點照樣有效，一排照片的節奏在手機上也還是對齊的。 */

/* 兩張並排：每一格套同一個比例，兩張的底線就對齊了。
   這是這個功能最實際的用途——一張 3:2、一張 4:5 並排時高度不一樣，
   讀者第一眼看到的是「沒對好」，不是那兩張照片的關係。
   兩張各自有自己的焦點，所以裁切之後仍然可以各自對準主體。 */
.cvf-two.cvf-ar .cvf-cell { flex: 1 1 0; width: auto; margin-inline: 0; }
/* 上下排時每一格各分一半的高度預算，寬度跟著換算，再置中。 */
.cvf-two.cvf-ar.cvf-pair-stack .cvf-cell {
  max-width: calc(((100svh - var(--cvf-room)) / 2 - 12px) * var(--cvf-ar));
  margin-inline: auto;
}
@media (max-width: 700px) {
  /* 手機一律上下排，高度預算跟著減半。 */
  .cvf-two.cvf-ar .cvf-cell {
    max-width: calc(((100svh - var(--cvf-room)) / 2 - 12px) * var(--cvf-ar));
    margin-inline: auto;
  }
}

/* ---- 說明文字 ---- */
.cvf-cap {
  margin: 0;
  font-size: 12.5px;
  letter-spacing: .04em;
  line-height: 1.6;
  color: var(--muted, #8a8a92);
  text-align: center;
  max-width: 620px;
}

/* 壓在角落：直接放在照片上。
   一定要有底襯——那一角夠不夠暗沒有人能事先保證，照片還會被換掉。
   在暗照片上這層漸層幾乎看不出來，在亮照片上剛好把字撐住。
   讀不到的字是失敗，多一點點暗只是保守。 */
.cvf-cap-bl .cvf-cap,
.cvf-cap-br .cvf-cap {
  position: absolute;
  bottom: 0;
  z-index: 2;
  max-width: min(56ch, 46%);
  margin: 0;
  padding: 42px 20px 16px;
  color: #f4f4f2;
  text-shadow: 0 1px 10px rgba(0, 0, 0, .7);
}
.cvf-cap-bl .cvf-cap { left: 0; text-align: left;
  background: linear-gradient(to top right, rgba(6,6,10,.72), rgba(6,6,10,0) 72%); }
.cvf-cap-br .cvf-cap { right: 0; text-align: right;
  background: linear-gradient(to top left, rgba(6,6,10,.72), rgba(6,6,10,0) 72%); }
/* 角落說明時，說明是 .cvf-stage 的絕對定位子元素 */
.cvf-cap-bl, .cvf-cap-br { position: relative; }

.cvf-cap-none .cvf-cap { display: none; }

/* ---- 襯底色 ---- */
/* 淺色或高調照片放在接近黑的底上會像浮在半空中。
   指定一個底色之後，照片外圍那一圈由它接住。 */
.cvf-hasbg { background: var(--cvf-bg, transparent); padding: clamp(18px, 3vh, 46px); border-radius: var(--r-img, 3px); }
/* 滿版時照片自己就佔滿整個視窗，襯底沒有地方可以露出來。
   視窗一窄、滿版失效之後，襯底要跟著回來——所以這條也綁同一個門檻。 */
@media (min-width: 1200px) {
  .cvf-fit-cover.cvf-hasbg { padding: 0; }
}

/* ---- 光暈／陰影 ---- */
/* 主題的全站設定會給 .sw-page 裡的圖片加 drop-shadow。
   有些照片自己的邊緣就是亮的（逆光、白背景），再加一圈光只會髒，
   所以這個區塊可以個別關掉。 */
html .cvf-nofx .cvf-img { filter: none; }
/* 滿版出血本來就沒有邊緣可以發光，一律關掉省去每一格的濾鏡計算。
   窄視窗下它變回完整顯示，四周重新有了邊緣，光暈也就該跟其他照片一樣回來。 */
@media (min-width: 1200px) {
  html .cvf-fit-cover .cvf-img { filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cvf-img { will-change: auto; }
}

/* ---- 燈箱（1.16.0） ----
   有燈箱的照片要看得出可以點。游標用 zoom-in（跟燈箱裡放大前的游標一致），
   自訂游標的圓環則靠 data-hover 放大——那一段由主題的腳本在綁燈箱時補上，
   不寫在 HTML 裡，因為沒有 JavaScript 時燈箱本來就不會運作，
   先畫一個「看起來能點但點了沒反應」的樣子比不畫更糟。 */
.cvf-lb .cvf-cell{cursor:zoom-in}
.cvf-lb .cvf-cell .cvf-img{transition:opacity .35s var(--ease,ease)}
.cvf-lb .cvf-cell:hover .cvf-img{opacity:.86}
.cvf-lb .cvf-cell:focus-visible{outline:2px solid var(--accent,#c9a35b);outline-offset:4px;border-radius:2px}
@media (prefers-reduced-motion:reduce){
  .cvf-lb .cvf-cell .cvf-img{transition:none}
}

/* ---- 空的圖說列（1.19.1） ----

   圖說統一放在圖下之後，沒有寫圖說的那些如果整列不存在，
   有圖說與沒圖說的兩張照片總高度就會差一列。那一點差距在單張上
   看不出來，連續滾過九張就變成節奏在跳。
   12.5px × 1.6 的行高 ＝ 20px，跟有字的那一列對齊。 */
.cvf-cap-empty { min-height: 20px; }
