/* ==========================================================================
   站台樣式
   --------------------------------------------------------------------------
   顏色、字體、欄數這些值不寫在這裡 —— 它們由 build.mjs 依照
   content/site.json 產生成 :root 變數注入到每頁的 <head>。
   要改風格請改 site.json，然後跑 `node build.mjs`。
   下面每個 var() 都有 fallback，所以這份 CSS 單獨開也不會爛掉。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 重置
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  background: var(--bg, #fff);
  color: var(--ink, rgba(0, 0, 0, .75));
  font-family: var(--font-body, sans-serif);
  /* 舊站 bodycopy 是 1.4rem / 行高 1.2，這裡沿用。想放大改 site.json 的 type.bodySize */
  font-size: var(--body-size, 1.4rem);
  line-height: var(--body-lh, 1.2);
  /* 正文字重。在 site.json 的 type.bodyWeight，標題是 type.headingWeight。
     兩者現在差 200（400 與 600），層次夠明顯又不會太重。 */
  font-weight: var(--body-weight, 400);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* 用 62.5% 讓 1rem = 10px，方便對照原站的 1.4rem 等數值。
   注意：Bito 是 16px 基準，所以從那邊抄過來的數值都要換算 ——
   他們的 1.5rem 欄距 = 24px = 這裡的 2.4rem。 */
html { font-size: 62.5%; }

/* 左右邊界。內容寬度上限是 --max，超過就居中，但邊界永遠至少留 --pad。
   只能用在 padding 上（裡面的 100% 要對容器寬度計算）。 */
:root {
  --edge: calc(max(0px, (100% - var(--max, 160rem)) / 2) + var(--pad, 4rem));
}

img, svg, video { display: block; max-width: 100%; height: auto; }
img { border: 0; padding: 0; vertical-align: bottom; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

/* ---- 自訂游標 ----
   一般狀態是粉紅圓點，滑到可以點的東西變灰。
   --cursor-default / --cursor-link 由 build.mjs 依 site.json 的 cursors 注入，
   值本身已經帶 auto / pointer 當 fallback。沒有產生圖檔時變數不存在，
   下面的 var() fallback 接手，行為就跟一般網站一樣。
   這幾條必須放在上面 button 那條重置之後，否則 button 會拿不到灰色游標。
   圖檔產生方式：node tools/make-cursors.mjs */
html { cursor: var(--cursor-default, auto); }
a, button, summary, [role="button"], .thumbnail { cursor: var(--cursor-link, pointer); }
/* 輸入框保留 I 型游標，不然看不出可以打字（目前站上沒有表單，先擋著） */
input, textarea { cursor: text; }

/* ---- 跟隨式游標（參考 therocketpanda.com）----
   平滑跟隨的粉紅圓點，滑到可點擊的東西時放大，有 data-cursor 屬性的還會顯示字。

   隱藏系統游標的規則**只在 JS 成功接手後才生效**（html.has-cursor 是 JS 加的）。
   寫死在靜態 CSS 裡的話，JS 一出錯就變成整站完全沒有游標 —— 那比沒做這個效果
   糟得多。JS 沒跑就沿用上面那組 PNG 圖檔游標，剛好是自然的降級。

   只在真的有滑鼠的裝置啟用（hover: hover 且 pointer: fine），
   觸控裝置根本沒有游標可跟。 */
@media (hover: hover) and (pointer: fine) {
  html.has-cursor,
  html.has-cursor * { cursor: none !important; }
}

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  pointer-events: none;
  /* JS 每一格都覆寫 transform，所以這一層不能有 transition，否則會跟計算打架 */
  will-change: transform;
  mix-blend-mode: var(--cursor-blend, normal);
}

/* 真正看得到的圓在內層。放大縮小做在這一層，transition 才不會影響外層的跟隨。

   居中用 translate(-50%, -50%) 而不是負 margin：顯示標籤時膠囊會變寬，
   負 margin 就不再等於一半、長標籤會偏掉。translate 的百分比是相對自己的尺寸，
   而 scale 以中心為原點，所以兩個疊在一起仍然是精準居中。 */
.cursor-ring {
  display: grid;
  place-items: center;
  width: var(--cursor-follow-size, 16px);
  height: var(--cursor-follow-size, 16px);
  border-radius: 100px;
  background: var(--cursor-follow-color, #ff5b90);
  transform: translate(-50%, -50%) scale(1);
  transition: transform .3s cubic-bezier(0.16, 1, 0.3, 1),
    background-color .3s ease;
}

/* 滑到可點擊的東西：放大。倍率是「放大後的直徑 ÷ 原直徑」，由 build.mjs 算好。 */
.cursor.is-hover .cursor-ring { transform: translate(-50%, -50%) scale(var(--cursor-grow, 4)); }

/* 有 data-cursor="文字" 的元素：圓變成一個裝得下字的膠囊。
   這時候不放大（膠囊本身就是大的），所以 scale 回到 1。 */
.cursor.has-label .cursor-ring {
  width: auto;
  height: auto;
  min-width: var(--cursor-label-size, 76px);
  min-height: var(--cursor-label-size, 76px);
  padding: 0 1.2rem;
  transform: translate(-50%, -50%) scale(1);
}
.cursor-label {
  font-family: var(--font-display, sans-serif);
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cursor-label-color, #fff);
  white-space: nowrap;
  opacity: 0;
  transition: opacity .2s ease;
}
.cursor.has-label .cursor-label { opacity: 1; }

/* 開了「減少動態」就不要放大縮小，但游標還是要跟著（不然沒有游標可用）。
   跟隨本身在 JS 端改成瞬間對位，沒有拖曳感。 */
@media (prefers-reduced-motion: reduce) {
  .cursor-ring,
  .cursor-label { transition: none; }
}
ul, ol { list-style: none; padding: 0; }
a { color: inherit; text-decoration: none; }
a:active { opacity: 0.7; }

:focus-visible {
  outline: 2px solid var(--accent, #f02);
  outline-offset: 3px;
}

::selection { background: var(--accent, #f02); color: #fff; }

i, em { font-style: italic; }
b, strong { font-weight: bolder; }
sub, sup { position: relative; vertical-align: baseline; }
sub { top: 0.3em; }
sup { top: -0.4em; }
s { text-decoration: line-through; }

hr {
  background: rgba(127, 127, 127, 0.2);
  border: 0;
  height: 1px;
  display: block;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* --------------------------------------------------------------------------
   2. 排版
   -------------------------------------------------------------------------- */
/* 舊站 h1 是 DM Sans 700、行高 1.1，顏色 75% 黑 */
h1, h2, h3 {
  font-family: var(--font-display, sans-serif);
  font-weight: var(--heading-weight, 700);
  line-height: 1.1;
  letter-spacing: 0;
  text-transform: none;
}

.display-xl { font-size: var(--hero-size, clamp(2.6rem, 4.5vw, 5.2rem)); }
.display-l  { font-size: var(--title-size, 2.2rem); }
.display-m  { font-size: 1.8rem; }

.body-text { max-width: 62ch; }
.body-text p + p { margin-top: 1.2em; }

/* 舊站 .gallery_image_caption：mundial 400、1.4rem、30% 黑、行高 1.2 */
.caption {
  font-family: var(--font-caption, sans-serif);
  font-size: var(--caption-size, 1.4rem);
  font-weight: 400;
  font-style: normal;
  line-height: 1.2;
  color: var(--caption-color, rgba(0, 0, 0, 0.3));
}

/* ---- 文字顏色只有兩種：深灰與黑。粉紅只出現在 hover。 ----
   .link-accent 是次要連結（社群、聯絡、上下篇），用深灰。
   內文行間的連結用黑，比周圍的 75% 灰重一點，看得出是連結。 */
.link-accent { color: var(--link, #252525); }
.prose a, .body-text a, .case-gallery a, .case-blurb a, .info a { color: var(--ink-strong, #000); }

/* 舊站 bodycopy a:hover 是 rgba(255, 91, 144, 1)。
   所有「帶連結的文字」滑過都變粉紅，包含縮圖標題。 */
.link-accent:hover,
.prose a:hover,
.body-text a:hover,
.case-gallery a:hover,
.case-blurb a:hover,
.info a:hover,
.case-nav a:hover,
.footer a:hover,
.thumbnail:hover .thumbnail-mobile-info .thumbnail-name {
  color: var(--accent-hover, #ff5b90);
}

.link-accent:active { color: var(--accent-active, #252525); }

/* --------------------------------------------------------------------------
   3. 版面容器
   -------------------------------------------------------------------------- */
.shell {
  padding-inline: var(--pad, 3.5rem);
}
@media (max-width: 700px) {
  :root { --pad: 2rem; }
}

.skip {
  position: absolute;
  left: 1rem; top: -100px;
  z-index: 200;
  background: var(--ink, #000);
  color: var(--bg, #fff);
  padding: 0.8rem 1.2rem;
  font-size: 1.4rem;
}
.skip:focus { top: 1rem; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   4. 導覽
   原站是絕對定位在左上角 35px 的小選單（#tag_menu），這裡沿用那個位置感，
   但改成 sticky，長頁面捲動時不會消失。
   -------------------------------------------------------------------------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  /* 上下左右 35px 對應舊站 #tag_menu 的 top/left: 35px */
  padding: 3.5rem var(--edge) 2rem;
  display: flex;
  /* 右邊那組連結要對齊 logo 的哪一邊。logo 是一個有高度的圖（約 148px），
     所以這個值看得很明顯。設定在 site.json 的 header.navAlign。 */
  align-items: var(--nav-align, flex-end);
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  /* 一開始沒有背景，跟頁面融在一起（跟舊站在最上面時的樣子一致） */
  background: transparent;
  transition: transform .4s cubic-bezier(.22, .8, .25, 1),
              background-color .3s ease,
              box-shadow .3s ease;
}

/* 捲離頂部後才給背景，否則壓在圖片上會看不清楚。

   哪些頁面要給背景由 site.json 的 header.solidOnScroll 決定，值會寫進
   <html data-header-solid>：
     index-only  只有首頁（現在的設定）——「除了首頁其他都透明底」
     always      每一頁
     never       都不給

   ⚠ 作品內頁選 index-only 或 never 的話，導覽列捲到圖片上時是透明的，
   深灰的連結壓在深色圖上會看不清楚。這是刻意接受的取捨。 */
[data-header-solid="always"] .nav.is-scrolled,
[data-header-solid="index-only"][data-page="index"] .nav.is-scrolled {
  background: var(--bg, #fff);
  box-shadow: 0 1px 0 rgba(0, 0, 0, .08);
}

/* 作品內頁：導覽列改成 fixed，封面才能頂到視窗最上緣。
   sticky 是佔流排空間的，所以封面會被推到導覽列下面；改成 fixed 之後
   <main> 從 y=0 開始，封面就是畫面上的第一個東西，導覽列浮在它上面。
   不必額外補 padding —— 封面本身就很高，後面的內容自然接在它下面。

   ⚠ 一定要加 [data-cover]（只有真的有封面的頁面才有這個屬性）。
   沒有封面的作品頁 —— Reel 就是，它沒有縮圖 —— 第一個元素是資訊列，
   導覽列脫離流排之後它會從 y=0 開始、直接被導覽列疊住。
   2026-08-21 真的發生過。 */
[data-page="work"][data-cover] .nav {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
}

/* 往下捲時收起來。往上捲會移除這個 class。 */
.nav.is-hidden {
  transform: translateY(-100%);
}

/* 選單開著、或有元素在導覽列內取得焦點時，不准躲起來 */
.nav:focus-within {
  transform: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
  .nav.is-hidden { transform: none; }
}

.nav-brand {
  font-family: var(--font-display, sans-serif);
  font-size: 1.8rem;
  letter-spacing: 0.02em;
}

/* 動態 logo。舊站顯示寬度 398px，窄螢幕按比例縮到不超過一半版面。 */
.nav-brand-logo {
  display: block;
  flex: none;
  line-height: 0;
  width: min(var(--logo-width, 398px), 46vw);
}
/* img 是動畫 WebP（現在的做法），video 是舊的 MP4 做法，兩種都撐住 */
.nav-brand-logo video,
.nav-brand-logo img {
  display: block;
  width: 100%;
  height: auto;
  /* 不加圓角與陰影，保持跟舊站一樣的乾淨感 */
}

.nav-links {
  display: flex;
  align-items: baseline;
  gap: 1.8rem;
  /* 字級、字重、往上抬多少都在 site.json 的 header（navSize / navWeight / navLift）。
     navLift 是靠 margin-bottom 把整組往上推 —— 因為 align-items 是 flex-end，
     底部留白就等於整組上移。行高壓成 1 是刻意的：正文行高 1.5 會在文字下方
     留一段看不見的空白，貼齊 logo 底部時會顯得往下沉。 */
  font-size: var(--nav-size, 1.5rem);
  font-weight: var(--nav-weight, 400);
  line-height: 1;
  margin-bottom: var(--nav-lift, 0);
}
/* 舊站導覽是 bodycopy 連結：平常黑字、滑過變粉紅 */
.nav-links a {
  color: var(--ink-strong, #000);
  /* 壓在深色封面上時會換成白字，換色要滑順一點 */
  transition: color .3s ease;
}
.nav-links a:hover { color: var(--accent-hover, #ff5b90); }

/* 封面在導覽列後面那塊偏暗 → 連結改白字。
   data-cover-dark 由 build.mjs 依 projects.json 的 coverTopDark 輸出
   （tools/set-card-colors.mjs 量的）；.is-over-cover 由 site.js 依捲動位置加，
   兩個條件都成立才換 —— 只看前者的話，捲過封面之後白字會消失在白底上。 */
[data-cover-dark] .nav.is-over-cover .nav-links a { color: #fff; }
[data-cover-dark] .nav.is-over-cover .nav-links a:hover { color: var(--accent-hover, #ff5b90); }
.nav-links a:active { color: var(--accent-active, #252525); }
/* 目前所在頁：深灰加粗體。用字重標示比換顏色更明顯，
   而且不必再多一個顏色進來（整站文字只有深灰與黑）。 */
/* 當頁指示：只把顏色調淡。
   2026-08-21 試過用 ::before 畫一圈粉紅，使用者看過之後決定不要圈，改成淺灰。
   淡色的邏輯是「這一頁你已經在看了」，所以退到背景去，不搶其他項。
   字重刻意不動 —— navCurrentWeight 跟 navWeight 現在都是 600，差別純粹靠顏色。 */
.nav-links a[aria-current="page"] {
  color: var(--nav-current, #252525);
  font-weight: var(--nav-current-weight, 700);
}
/* 目前頁滑過時仍然變粉紅，維持「連結都會變粉紅」的一致性 */
.nav-links a[aria-current="page"]:hover { color: var(--accent-hover, #ff5b90); }

/* --------------------------------------------------------------------------
   5. 首頁 hero
   -------------------------------------------------------------------------- */
/* 首頁大標。字級、字重、斜體、行距、字距、行寬、對齊都在 site.json 的 hero，
   後台的「版面設定 → 首頁大標」調得到。

   對齊要同時做兩件事：文字本身的 text-align，以及整個區塊往哪邊靠（--hero-margin）。
   只設 text-align 的話區塊仍然被 max-width 綁在左邊，選「置中」看起來只是
   「在左半邊置中」—— 這是這裡最容易做錯的一點。 */
.hero {
  padding: clamp(4rem, 12vh, 12rem) var(--edge) clamp(5rem, 10vh, 10rem);
  text-align: var(--hero-align, left);
}
.hero > * {
  max-width: var(--hero-max, 90rem);
  margin: var(--hero-margin, 0 auto 0 0);
}
.hero .display-xl {
  font-weight: var(--hero-weight, 700);
  font-style: var(--hero-style, normal);
  line-height: var(--hero-lh, 1.1);
  letter-spacing: var(--hero-ls, 0);
}
/* 副標。字級獨立，其餘跟著大標走，這樣改一個值兩行不會脫節。 */
.hero .display-l {
  font-size: var(--hero-sub-size, 2.2rem);
  font-style: var(--hero-style, normal);
  line-height: var(--hero-lh, 1.1);
  letter-spacing: var(--hero-ls, 0);
}
.hero > * + * { margin-top: var(--hero-gap, 1.2rem); }

/* --------------------------------------------------------------------------
   6. 縮圖網格
   欄數、比例、間距都由 build.mjs 從 site.json 注入（--grid-cols、--span 等）。

   版型參考 bito.tv：12 欄網格，每件作品佔 4 欄 = 一行三格，滑過時色塊由上往下
   蓋住縮圖、文字延遲浮現。跟 Bito 的差別是他們一行兩格、而且每件作品在後台另外
   備了直式素材；這裡只有一套素材，直式高卡是裁切的。
   -------------------------------------------------------------------------- */
.thumbnails {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols, 12), minmax(0, 1fr));
  gap: var(--grid-gutter, 2.4rem);
  /* 內容寬度上限 --max，超過就居中。用 padding 而不是 max-width + auto margin，
     這樣同一條算式可以套在 hero 與頁尾上，左邊界對得齊。 */
  padding-inline: var(--edge);
  padding-bottom: clamp(6rem, 12vh, 12rem);
  align-items: start;
}

/* 可變欄寬。預設值來自 :root 的 --span（一行三格 = 4 欄），
   個別作品想放大就在 projects.json 加 span / spanTablet / spanMobile。 */
.thumbnail {
  display: block;
  position: relative;
  overflow: hidden;
  grid-column: span var(--span, 4);
}
@media (max-width: 1100px) {
  .thumbnail { grid-column: span var(--span-t, 6); }
}
@media (max-width: 620px) {
  .thumbnail {
    grid-column: span var(--span-m, 12);
    /* 手機的標題在圖片下方，不能被裁掉 */
    overflow: visible;
  }
}

.thumbnail-frame {
  position: relative;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.04);
  aspect-ratio: var(--card-ratio, 631 / 348);
}
.thumbnail-frame img,
.thumbnail-frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---- 直式高卡 ----
   佔兩列高，讓網格不是死板的方格。哪幾件當高卡是 build.mjs 算的，會優先挑
   原本就是直式的作品，並且驗證過不會在網格中間留下空洞。

   高度是 ::before 用百分比 padding 撐出來的：兩列 + 一個 row-gap
   = 200% / 比例 + gutter。padding 的百分比是對「自身寬度」計算的，所以不必知道
   實際像素寬，換比例或縮放視窗都會自己跟上。
   圖片改成絕對定位鋪滿整張卡 —— 但不能只靠絕對定位，那樣高卡在文件流裡高度是
   零，一旦某一列剛好整列都是高卡，該列就會塌成一條細線。 */
.thumbnail--tall { grid-row: span 2; }
.thumbnail--tall::before {
  content: '';
  display: block;
  padding-top: calc(200% / var(--card-ratio-num, 1.8132) + var(--grid-gutter, 2.4rem));
}
.thumbnail--tall .thumbnail-frame {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
}

/* ---- 滑過的色塊 ----
   顏色是每件作品自己的（--card-color，由 tools/set-card-colors.mjs 從縮圖取平均色
   寫進 projects.json）。沒有顏色就退回強調色。 */
.thumbnail-overlay {
  position: absolute;
  inset: 0;
  background: var(--card-color, var(--accent, #f02));
  transform: translateY(-101%);
  transition: transform .7s cubic-bezier(.89, -.01, .37, 1);
  pointer-events: none;
}
.thumbnail:hover .thumbnail-overlay,
.thumbnail:focus-visible .thumbnail-overlay { transform: translateY(0); }

.thumbnail-info {
  position: absolute;
  top: 0;
  left: 0;
  padding: 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  color: #fff;
  opacity: 0;
  transition: opacity .7s;
  transition-delay: .3s;
  pointer-events: none;
}
/* 淺色底的作品要用黑字，由 projects.json 的 cardColorDark 決定 */
.thumbnail-info.is-dark { color: #000; }
.thumbnail:hover .thumbnail-info,
.thumbnail:focus-visible .thumbnail-info { opacity: 1; }

.thumbnail-name {
  font-size: 1.8rem;
  /* 這是作品標題，所以跟著 --heading-weight 走。
     寫死數字的話改字重時會漏掉這裡，還可能指到一個沒載入的字重。 */
  font-weight: var(--heading-weight, 700);
  line-height: 1.2;
}
.thumbnail-meta {
  font-size: 1.6rem;
  line-height: 1.2;
}

/* 手機不用色塊，標題放到圖片下方 */
.thumbnail-mobile-info { display: none; }
@media (max-width: 620px) {
  .thumbnail-overlay, .thumbnail-info { display: none; }
  .thumbnail-mobile-info {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-top: 0.8rem;
  }
  .thumbnail-mobile-info .thumbnail-name { font-size: 1.6rem; color: var(--ink, #000); }
  .thumbnail-mobile-info .thumbnail-meta {
    font-size: 1.4rem;
    color: var(--caption-color, rgba(0, 0, 0, .3));
  }
  /* 一行一格時直式高卡沒有意義，回到一般比例 */
  .thumbnail--tall { grid-row: span 1; }
  .thumbnail--tall::before { display: none; }
  .thumbnail--tall .thumbnail-frame {
    position: relative;
    aspect-ratio: var(--card-ratio, 631 / 348);
  }
}
/* 平板一行兩格，三欄的咬合節奏換成兩欄會留洞，所以取消直式高卡 */
@media (max-width: 1100px) and (min-width: 621px) {
  .thumbnail--tall { grid-row: span 1; }
  .thumbnail--tall::before { display: none; }
  .thumbnail--tall .thumbnail-frame {
    position: relative;
    aspect-ratio: var(--card-ratio, 631 / 348);
  }
}

@media (prefers-reduced-motion: reduce) {
  .thumbnail-overlay, .thumbnail-info { transition-duration: .01ms; }
}

/* --------------------------------------------------------------------------
   7. 作品內頁
   2026-08-20 從原站的「一張圖接一張圖往下堆」改成參考 bito.tv 的內頁：
   封面 + 資訊列剛好填滿第一屏，往下才是滿寬的圖片直排。

   左右邊界與寬度上限跟首頁網格共用 --pad / --max，封面的左邊緣才會對齊
   導覽列的 logo 與首頁第一張縮圖。
   -------------------------------------------------------------------------- */
.case {
  padding: 0 var(--pad, 3.5rem) clamp(6rem, 12vh, 12rem);
  max-width: var(--max, 160rem);
  margin-inline: auto;
}

/* ---- 封面 ----
   高度由 site.js 算成「視窗高 - 資訊列高」後寫進 --cover-h，所以捲動前剛好
   看到封面加上作品名與年份。JS 沒跑（或 data-fill="false"）時就用注入的
   預設值，版面不會壞。圖一律裁切填滿，因為素材比例從正方到直式都有。 */
.case-cover {
  /* 夾制交給 CSS 而不是 JS：JS 只寫一個 px 值進 --cover-h，min/max 是什麼單位
     都由 clamp 處理。沒有下限的話，敘述特別長的那幾件會把封面壓成一條細線。 */
  height: clamp(var(--cover-h-min, 45vh), var(--cover-h, 70vh), var(--cover-h-max, 92vh));
  overflow: hidden;
  background: rgba(0, 0, 0, 0.06);

  /* 捲動時往內縮 + 長出圓角。
     捲動前橫向撐滿整個視窗（連 .case 的左右邊界都突破），往下捲時左右一起收進來。
     --cover-inset-now 與 --cover-radius-now 都是 site.js 依捲動進度寫入的，
     兩者在捲動前都是 0。

     撐滿寬度用 --vw（site.js 寫入 documentElement.clientWidth）而不是 100vw：
     100vw 在 Windows 上會包含滾動條寬度，封面會比看得到的區域寬十幾像素、右邊被切掉。

     margin-left 那條是把元素從「置中且有邊界的容器」推回視窗左緣的標準算式：
     50% 是容器寬的一半，減掉視窗寬的一半就回到視窗左緣，再加上要縮進來的量。

     這裡不加 transition —— JS 每一格都會更新，加了會跟捲動打架變成拖尾。 */
  width: calc(var(--vw, 100vw) - 2 * var(--cover-inset-now, 0px));
  margin-left: calc(50% - var(--vw, 100vw) / 2 + var(--cover-inset-now, 0px));
  border-radius: var(--cover-radius-now, 0);
}
/* 封面素材。裁切填滿，所以「看得到哪一塊」由 object-position 決定。

   每件作品可以在後台調位置與縮放，build.mjs 會把 object-position、transform: scale
   與 transform-origin 直接寫在這個元素的 style 上（見 coverMediaStyle()）。
   這裡只放預設值 —— 沒調過的作品就是居中、不放大，跟以前一樣。

   transform-origin 會跟著 object-position 一起設成同一組百分比，兩者不同步的話
   放大永遠從正中央長出去：使用者把構圖拖到上緣，一放大又跑回中間，等於白拖。 */
.case-cover > * {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
  margin: 0;
}

/* ---- 資訊列 ----
   12 欄。左邊是作品名與敘述，右邊是類型、年份這些欄位。

   2026-08-21 改成參考 therocketpanda.com 的作品內頁：敘述放大成整段的主角
   （原本是 1.6rem，跟一般段落一樣大），右邊的欄位從 2×2 改成單一直排、
   每格左邊一條細線、彼此拉開很大的間距，上下留白也拉大，所以這一段自成一屏。

   欄位怎麼分、字多大、間距多少都在 site.json 的 case 裡（blurbSize、blurbSpan、
   factsCol、factsGap、infoSpacing），後台的「版面」頁調得到。 */
.case-info {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols, 12), minmax(0, 1fr));
  gap: var(--grid-gutter, 2.4rem);
  padding: var(--info-pad, 10rem) 0;
}
.case-name { grid-column: span var(--info-span, 8); }

/* 沒有敘述的作品（52 件裡有 21 件）。大字版型靠大量留白撐起來，但左邊只有
   一個標題時，同樣的留白只是一片空白，右邊兩個欄位還被拉開快 250px。
   build.mjs 會在這種頁面的 .case-info 上加 data-lean。 */
.case-info[data-lean] { padding: calc(var(--info-pad, 10rem) * 0.45) 0; }
.case-info[data-lean] .case-facts { gap: 3.2rem; }
.case-title {
  /* 敘述放大之後，標題反而比它小 —— 這是刻意的：小字粗體的作品名當標籤，
     底下接大字的引言段落。參考站的作品名不在這一段裡（壓在封面上），
     但這個站的封面沒有壓字，所以標題必須留在這裡。 */
  font-family: var(--font-display, sans-serif);
  font-size: clamp(2.2rem, 2.6vw, 2.8rem);
  font-weight: var(--heading-weight, 700);
  line-height: 1.5;
  margin: 0;
}

/* 敘述。

   行寬一定要有上限：左邊的欄位是 8 欄（1920 螢幕上約 990px），正文字級下
   換算成一行 150 個字元，眼睛換行時會找不到下一行的開頭。--blurb-measure
   就是這個上限（預設 75ch，約 660px），所以文字區塊會落在欄位的左半部，
   右邊那段空白是刻意留的，不是版面沒填滿。

   段距用 em 而不是 rem，字級一調就跟著走。 */
.case-blurb {
  margin-top: 3.2rem;
  max-width: var(--blurb-measure, 75ch);
  font-size: var(--blurb-size, 1.6rem);
  line-height: var(--blurb-lh, 1.6);
}
.case-blurb p { margin: 0; }
.case-blurb p + p { margin-top: 1em; }

/* 敘述放在資訊列會直接吃掉封面的高度，所以先收到 --blurb-lines 行。
   超出的話 site.js 才把展開按鈕顯示出來 —— 沒溢出就不該有按鈕。
   line-clamp 需要 -webkit- 前綴，各家瀏覽器都還是認這個寫法。 */
.case-blurb[data-clamp]:not(.is-open) {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--blurb-lines, 4);
  overflow: hidden;
}
.case-more {
  margin-top: 1.2rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 1.3rem;
  color: var(--link, #252525);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}
.case-more:hover { color: var(--accent-hover, #ff5b90); }

/* 右邊一欄。參考圖是單一直排、每格左邊一條細線、間距拉得很開。
   細線的顏色由 --facts-rule 控制，關掉時是 transparent 而不是拿掉 border，
   這樣文字不會左右位移。 */
.case-facts {
  grid-column: var(--facts-col, 10) / -1;
  display: flex;
  flex-direction: column;
  gap: var(--facts-gap, 6.4rem);
  margin: 0;
}
.case-fact {
  padding-left: 1.6rem;
  border-left: 1px solid var(--facts-rule, rgba(0, 0, 0, 0.16));
}
/* 參考圖的標籤是小灰字，沒有大寫也沒有加字距（原本是 uppercase + 0.08em）。
   比值小一號，用 body-size 算出來，改字級的時候兩個一起動。 */
.case-facts dt {
  font-size: calc(var(--body-size, 1.4rem) * 0.94);
  opacity: 0.45;
}
.case-facts dd {
  margin: 0.5rem 0 0;
  font-size: var(--body-size, 1.4rem);
  line-height: 1.4;
  color: var(--ink-strong, #000);
}

/* ---- 圖片區 ----
   Bito 是每個媒體塊都 col-span-full 滿寬直排，這裡照做。
   原站 .content img 的 margin-bottom: 2rem 換成統一的區塊間距。 */
/* 圖片區是 12 欄網格，讓每個區塊可以指定放在哪幾欄 —— 滿版、並排、左右錯落
   都靠這一個機制（projects.json 的 col / span，後台區塊編輯器有下拉可選）。

   沒有指定的區塊佔滿一整列，行為跟改成網格之前完全一樣。
   row-gap 刻意保持 0、垂直間距仍然用各自的 margin-bottom —— 這樣現有 51 頁的
   間距一點都不會變，而且文字段落可以有自己較緊的間距（見下面的 p + p）。 */
.case-gallery {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--grid-gutter, 2.4rem);
  row-gap: 0;
}
.case-gallery > * { grid-column: 1 / -1; }

/* 圖片之間的垂直間距。原本沿用網格的 2.4rem 太擠了（參考站是 10em）。
   文字段落的上下距離另外設，見下面 .case-gallery > p。 */
.case-gallery > * { margin-bottom: var(--gallery-gap, 2.4rem); }

/* 寬度上限。--media-max 由 build.mjs 逐張算好寫在 style 屬性上：
   預設按比例收窄（讓所有媒體高度一致，就是一張 16:9 滿寬時的高度），
   個別圖片可以在 projects.json 那個 block 加 "width": "full" 或 "70%" 蓋掉。

   width: 100% 仍然保留，否則實際檔案比上限窄時不會撐開，寬度會忽大忽小。 */
.case-gallery > img,
.case-gallery > video,
.case-gallery > figure {
  display: block;
  width: 100%;
  height: auto;
  max-width: var(--media-max, 100%);
  margin-inline: auto;
}

/* 圓角（site.json 的 case.mediaRadius，參考站是 3em）。
   圖片與影片自己就能圓角；Vimeo 的 iframe 不行，要靠外層的 .embed 裁掉，
   所以那邊要 overflow: hidden。figure 的圓角掛在裡面的圖上，不然圖說也會被裁。 */
.case-gallery > img,
.case-gallery > video,
.case-gallery > figure img,
.case-gallery > figure video {
  border-radius: var(--media-radius, 0);
}
/* 有圖說的時候上限掛在 figure 上（--r 也寫在 figure 上），圖說才會跟圖片左邊對齊。
   圖片本身就填滿那個已經收窄的 figure，不要再收一次。 */
.case-gallery > figure img,
.case-gallery > figure video {
  display: block;
  width: 100%;
  height: auto;
}
.case-gallery figcaption {
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}
figure { margin: 0; }

/* 圖片之間的文字不要跟圖一樣滿版，限制在好讀的寬度。
   上下距離自己設，不吃 --gallery-gap（圖片之間要很鬆，文字不用）。 */
.case-gallery > p {
  max-width: 62ch;
  font-size: var(--body-size, 1.4rem);
  line-height: 1.5;
  margin-block: clamp(2rem, 4vh, 4rem);
}
.case-gallery > p + p { margin-top: -0.8rem; }

/* 整段橫幅：連續同底色的區塊共用一條左右滿版的色帶（projects.json 的 bg）。

   滿版的做法跟 .case-cover 同一套：.case 有 --pad 的左右內距、又被 --max 收窄，
   所以要先突破它再把內容收回原本的欄寬 —— 這樣色帶裡的圖片跟色帶外的對得齊。

   **不能用 100vw**：Windows 上它包含滾動條寬度，色帶會比看得到的區域寬十幾像素、
   右邊被切掉。--vw 是 site.js 寫入的 documentElement.clientWidth。

   文字顏色由 build.mjs 依底色亮度算好寫在 style 上（深底翻白字），不在這裡處理。

   色帶裡面仍然是 .case-gallery，所以 .case-gallery > img 那些規則照常生效 ——
   這是刻意保留同一個 class 的原因，不然圖片的寬度與間距要再寫一份。 */
.case-band {
  width: var(--vw, 100vw);
  margin-left: calc(50% - var(--vw, 100vw) / 2);
  padding: var(--band-pad, 6rem) 0;
}
.case-band > .case-gallery,
.case-band > .case-info {
  max-width: var(--max, 160rem);
  margin-inline: auto;
  padding-inline: var(--pad, 3.5rem);
}
/* 資訊列自己就有 --info-pad 的上下內距，色帶不要再加一次（會變兩倍高）。 */
.case-band.is-info { padding-block: 0; }

/* 封面的色帶。封面要頂到最上面（導覽列壓在圖上），所以不能有上下內距；
   左右也不收 —— 封面自己會算滿版與縮排，色帶只是墊在它後面的一張色紙。

   封面裡面那層仍然用自己的 margin-left: calc(50% - --vw/2 + inset) 定位。
   包在滿版色帶裡之後，那個 50% 從「內容欄的一半」變成「視窗的一半」，
   算出來剛好是 0 + inset —— 結果跟原本一樣，所以定位不用改。 */
.case-band.is-cover { padding: 0; }
/* 段落與圖片自己的外距會疊在色帶的內距上，讓上下看起來比設定值鬆很多。
   第一塊與最後一塊的外距歸零，色帶的高度就由 --band-pad 說了算。 */
.case-band > .case-gallery > *:first-child { margin-top: 0; }
.case-band > .case-gallery > *:last-child { margin-bottom: 0; }
/* 深色色帶上的連結要跟著翻白，不然會剩下深灰的連結看不見 */
.case-band a { color: inherit; }

/* 置中版（site.json 的 case.galleryTextAlign: "center"，參考站的做法 ——
   他們左右各留 15em 把行寬收窄再置中）。行寬收得比靠左版更窄，
   因為置中的長行讀起來比靠左的長行更累（每行起點都在跳）。

   只管圖片之間的段落。資訊列裡的作品敘述不套用 —— 那裡是 12 欄版面的左半邊，
   置中會跟右邊的 Type／Year 對不起來。 */
[data-gallery-text="center"] .case-gallery > p {
  max-width: 52ch;
  text-align: center;
  margin-inline: auto;
}

/* 內頁小標題（Styleframe / Storyboard / Credit 這類） */
.case-section {
  font-family: var(--font-display, sans-serif);
  font-size: clamp(1.8rem, 2.4vw, 2.6rem);
  margin-top: clamp(3rem, 6vh, 5rem);
}

/* Vimeo 嵌入：保持 16:9 且隨寬度縮放 */
.embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: rgba(0, 0, 0, 0.06);
  /* Vimeo 的 iframe 自己吃不到 border-radius，要靠外層裁掉。
     參考站也是這樣做的（.videowrap 有 border-radius + overflow: hidden）。 */
  border-radius: var(--media-radius, 0);
  overflow: hidden;
}
.embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.case-nav {
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  margin-top: clamp(3rem, 6vh, 6rem);
  padding-top: clamp(3rem, 6vh, 6rem);
  border-top: 1px solid rgba(127, 127, 127, 0.2);
  font-size: 1.5rem;
}
.case-nav a { color: var(--link, #252525); }
.case-nav a:hover { color: var(--accent-hover, #ff5b90); }

/* 窄螢幕：資訊列的兩半疊起來，類型與年份仍然並排（字都很短，放得下）。
   Bito 在 ≤500px 是把網格改成 8 欄再用 order 重排；這裡只有兩塊，
   直接讓兩塊都滿寬就好，不必動欄數。 */
@media (max-width: 1100px) {
  .case-info { padding: calc(var(--info-pad, 10rem) * 0.55) 0 3.6rem; }
  .case-name,
  .case-facts { grid-column: 1 / -1; }
  /* 欄位改成橫排並列。窄畫面上單一直排會拉得很長，而且下面就是圖片區了 */
  .case-facts { flex-direction: row; flex-wrap: wrap; gap: 2.4rem 4rem; }
}

@media (max-width: 620px) {
  /* 手機上封面不該吃掉整個第一屏，否則要捲很久才看到作品名 */
  .case-cover { height: clamp(30vh, var(--cover-h, 50vh), 60vh); }

  /* 手機上一律滿寬。螢幕本來就窄，正方形再收到 56% 只剩指甲大小。
     這裡蓋掉 max-width 這個屬性，而不是改 --media-max ——
     那個變數寫在 style 屬性上，優先度比任何 CSS 規則都高，改不動。 */
  .case-gallery > img,
  .case-gallery > video,
  .case-gallery > figure { max-width: 100%; }

  /* 手機上也不要並排或錯落，全部拉成一整列。
     grid-column 是寫在 style 屬性上的，所以要用 !important 才蓋得掉 ——
     這是唯一一個真的需要 !important 的地方，其他都有更好的辦法。 */
  .case-gallery > * { grid-column: 1 / -1 !important; }
}

/* --------------------------------------------------------------------------
   8. Information 頁
   --------------------------------------------------------------------------
   2026-08-21 改成兩欄：左邊一張照片、右邊文字，上緣對齊。
   參考 https://bb-hlw.com/info（Adobe Portfolio 站）的實測值：

     版面      .tree-wrapper { display:flex } + valign-top
     兩欄比例   flex 89 : 111 → 44.5% / 55.5%
     欄間距     每欄左右各 4px 透明邊框 → 中間 8px
     左欄圖     寬 90%、padding-bottom 100%（正方形）
     右欄文字   max-width 750px
     小標      26px / 700 / 行高 34px / 上距 30px / 靠左
     正文      20px / 400 / 行高 28px / 段距 20px
     手機      display:block + flex:none → 上下堆疊

   抄過來時改掉的地方：

   ・**用 12 欄網格算，不照抄 flex 89:111。** 結果幾乎一樣（5/12 = 41.7% 對
     44.5%），但左右邊界會跟首頁與作品內頁對齊。參考站是獨立的 flex，沒有這個
     約束；這個站每一頁都吃同一組 --grid-cols 與 --edge。

   ・**正文顏色沒抄。** 參考站的正文是 #999（淺灰），在白底上對比只有 2.8:1，
     低於 4.5:1 的可讀性門檻 —— 那是設計選擇，但這一頁是履歷，被看不清楚的
     代價太高。維持全站的 --ink（75% 黑，對比 8.6:1）。

   ・**欄間距用站上的 --grid-gutter（24px）而不是 8px。** 8px 看起來像沒對齊
     的意外，不像刻意的緊貼。

   ・小標從 1.4rem 大寫加字距，改成 2rem 不大寫（參考站的做法）。她的小標本來
     就有 ✸ 這個字符，大寫化之後那個字符和英文混排會很雜。
   -------------------------------------------------------------------------- */
.info {
  padding: clamp(2rem, 5vh, 5rem) var(--edge) clamp(6rem, 12vh, 12rem);
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols, 12), minmax(0, 1fr));
  gap: var(--grid-gutter, 2.4rem);
  align-items: start;
}
/* 沒有照片時退回單欄，文字不要被壓在右半邊 */
.info-grid.is-single .info-main { grid-column: 1 / -1; }

.info-photo { grid-column: 1 / span var(--info-photo-span, 5); }
.info-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--info-photo-ratio, 1 / 1);
  object-fit: cover;
  border-radius: var(--media-radius, 0);
  background: rgba(0, 0, 0, 0.04);
}

.info-main {
  grid-column: var(--info-text-col, 7) / -1;
  /* 行寬上限。參考站是 750px，這裡預設 75rem = 750px（1rem = 10px）。 */
  max-width: var(--info-text-max, 75rem);
}

.info-title {
  font-family: var(--font-display, sans-serif);
  font-size: var(--info-title-size, 2.6rem);
  font-weight: var(--heading-weight, 700);
  line-height: 1.3;
  margin: 0;
}

.info-body {
  margin-top: clamp(1.6rem, 3vh, 3rem);
  font-size: var(--body-size, 1.4rem);
  line-height: 1.6;
}
.info-body p { margin: 0; }
.info-body p + p { margin-top: 1em; }

.info-block { margin-top: clamp(2.4rem, 5vh, 5rem); }
.info-block h2 {
  font-size: var(--info-heading-size, 2rem);
  font-weight: var(--heading-weight, 700);
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  margin: 0;
}
.info-list { margin-top: 1.2rem; font-size: var(--body-size, 1.4rem); line-height: 1.6; }
.info-list li + li { margin-top: 0.4rem; }

.contact-mail {
  display: inline-block;
  margin-top: 1.2rem;
  font-family: var(--font-display, sans-serif);
  font-size: var(--info-contact-size, 2.6rem);
  color: var(--link, #252525);
  word-break: break-word;
}
.contact-mail:hover { color: var(--accent-hover, #ff5b90); }
.info-social { margin-top: 1.6rem; }

/* 手機：兩欄堆疊，照片在上（參考站也是 display:block + flex:none）。
   這一段一定要放在上面那些基礎規則**之後** —— 選擇器的 specificity 一樣
   （都是單一 class），媒體查詢不會提高權重，所以誰在後面誰生效。
   第一次寫的時候放在前面，結果 .info-photo 的 span 5 又把它蓋回去，
   手機上照片變成 146px 的小方塊擠在文字旁邊。 */
@media (max-width: 620px) {
  .info-photo,
  .info-main { grid-column: 1 / -1; }
  .info-main { max-width: none; }
}

/* --------------------------------------------------------------------------
   9. 頁尾
   -------------------------------------------------------------------------- */
.footer {
  padding: 3rem var(--edge) 4rem;
  font-size: 1.3rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  color: var(--caption-color, rgba(0, 0, 0, 0.3));
}
.footer a { color: var(--link, #252525); }
.footer a:hover { color: var(--accent-hover, #ff5b90); }

/* 平台連結。頁尾是 space-between 的三欄：版權、平台、信箱。
   Information 頁不顯示這一組（它的聯絡區塊已經有了）。 */
.footer-social {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.8rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* --------------------------------------------------------------------------
   10. 列印
   -------------------------------------------------------------------------- */
@media print {
  .nav, .footer, .case-nav, .case-more { display: none !important; }
  body { background: #fff; color: #000; }
  /* 印出來不該裁封面，也不該把敘述收起來 */
  .case-cover { height: auto !important; }
  /* 放大是為了在固定高的框裡選構圖；印出來沒有那個框，縮放只會裁掉東西 */
  .case-cover > * { height: auto !important; object-fit: fill; transform: none !important; }
  .case-blurb[data-clamp] { display: block !important; overflow: visible !important; }
}
