/* ═══════════════════════════════════════════════════════════════════════════
   pages.css — 職業 / 外觀 / 探險實況 三頁的桌機設計層
   ─────────────────────────────────────────────────────────────────────────
   載入順序：style.css → layout.css → enhance.css → dexbook.css → 這一份 → mobile.css
   ⚠️ 規則一律包在 @media (min-width: 1024px)：手機由 mobile.css 負責（載在後面），
      這裡不可以留任何會外溢到窄螢幕的宣告。
   ⚠️ 頁面範圍用 :has() 認頁，不靠 body class（app.js 不在可改範圍內）：
        職業列表 → #app:has(> .jtree)
        外觀     → #app:has(#lookbody)（React 殼包在 .legacy-host 裡，grid 容器用 :is(#app, #app > .legacy-host):has(> #lookbody)）
        探險實況 → #app:has(> .legacy-host > .livebox)
   沿用 enhance.css 的語彙：--e1/--e2/--e3 三階陰影、--rim 紙張邊光、
   「精靈圖站在舞台上」（漸層底 + 腳下投影）、hover 浮起。
   ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 1024px) {

/* ═══════════════════════════════════════════════════════════════════════════
   🎖️ 職業頁 —— 使用者來這頁是要「選職業」，不是查技能表
   ─────────────────────────────────────────────────────────────────────────
   原本五欄卡片每一張權重都一樣：家族性格躲在 12px 灰字裡、一轉與二轉長得一模一樣、
   本季沒開的三四轉還跟它們排在同一條線上 —— 版型完全沒幫使用者做決定。
   主張：五個家族＝五張並排的「招募海報」。
     ① 家族頭像放大站上舞台，家族色變成真的色帶（不是 4px 邊）
     ② Lv10 起手的一轉放大成整欄的主角（你要先選的是這個）
     ③ Lv30 的分支用一條有標籤的岔路切開（「Lv30 選一條路」）
     ④ 三轉 / 四轉本季未開 → 一律沉到每欄最底，五欄切齊
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 起點：原本孤零零一張 260px 卡片，改成一條有敘事的起跑線 ── */
#app:has(> .jtree) .jtree-start {
  margin: 20px 0 16px;
  padding: 12px 20px 12px 14px;
  gap: 16px;
  border-radius: var(--rad-lg);
  border: 1.5px solid var(--line-strong);
  background: linear-gradient(100deg, var(--bg-paper) 0%, var(--card-wood) 62%, #fbeedd 100%);
  box-shadow: var(--e1), var(--rim);
}
#app:has(> .jtree) .jtree-start::before {
  content: "起點";
  order: -1; flex: 0 0 auto;
  padding: 7px 13px; border-radius: var(--rad-pill);
  font: 900 12px/1 Nunito, "Noto Sans TC", sans-serif; letter-spacing: .1em;
  color: var(--on-solid);
  background: linear-gradient(180deg, var(--accent-ink) 0%, var(--accent-ink-deep) 100%);
  box-shadow: 0 3px 10px rgba(230, 81, 0, .3);
}
#app:has(> .jtree) .jtree-start::after {
  content: "Lv10 到職業村找教官 —— 從下面五個家族裡選一條路走。";
  flex: 1 1 240px; min-width: 0;
  font-size: var(--fs-2xs); font-weight: 700; line-height: 1.7;
  color: var(--muted-brown);
}
#app:has(> .jtree) .jtree-start .jcard { flex: 0 0 238px; }

/* ── 五欄等高，海報才切得齊 ── */
#app:has(> .jtree) .jtree {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 16px;
  align-items: stretch;
}
/* grid → flex：只有 flex 的 margin-top:auto 能把「本季未開」壓到每欄最底 */
#app:has(> .jtree) .famcol {
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px;
  border-width: 1.5px; border-top-width: 4px;
  border-radius: var(--rad-lg);
  background: linear-gradient(180deg, var(--bg-paper) 0%, var(--bg-paper) 58%, var(--card-wood) 100%);
  box-shadow: var(--e2), var(--rim);
  transition: box-shadow var(--dur-3) var(--ease), transform var(--dur-3) var(--ease);
}
#app:has(> .jtree) .famcol:hover { box-shadow: var(--e3), var(--rim); }

/* 家族抬頭＝海報的招牌：滿版色帶 + 頭像站上舞台 */
#app:has(> .jtree) .famhead {
  position: relative;
  display: grid; grid-template-columns: 1fr; justify-items: center;
  gap: 5px; text-align: center;
  margin: -16px -16px 4px;
  padding: 16px 14px 13px;
  min-height: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 14px 14px 0 0;
  background: linear-gradient(180deg, var(--card-wood) 0%, var(--bg-paper) 100%);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--fc) 19%, var(--bg-paper)) 0%,
    color-mix(in srgb, var(--fc) 5%, var(--bg-paper)) 62%,
    var(--bg-paper) 100%);
}
/* 腳下的橢圓投影：頭像才像站在那裡，不是浮著 */
#app:has(> .jtree) .famhead::after {
  content: "";
  grid-row: 1; grid-column: 1; align-self: end; justify-self: center;
  width: 78px; height: 16px; margin-bottom: 1px; border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(110, 75, 40, .28) 0%, transparent 72%);
}
#app:has(> .jtree) .famhead .fportrait {
  position: relative; z-index: 1;
  grid-row: 1; grid-column: 1;
  width: 72px; max-height: 80px;
  filter: drop-shadow(0 4px 7px rgba(90, 60, 25, .26));
  transition: transform var(--dur-3) var(--ease);
}
#app:has(> .jtree) .famcol:hover .famhead .fportrait { transform: translateY(-3px); }
#app:has(> .jtree) .famhead .fn { font-size: var(--fs-md); letter-spacing: -.01em; margin-top: 4px; }
/* ⚠️ 海盜是「主屬 STR/DEX · HP 22~26/級」兩行，其他四家一行 →
      不預留兩行的高度，整欄的卡片就會比別人低 22px，五張海報切不齊。*/
#app:has(> .jtree) .famhead .fs {
  display: flex; align-items: center; justify-content: center;
  min-height: 2.9em;
  font-size: var(--fs-3xs); line-height: 1.45; color: var(--text-brown);
  max-width: 22ch; margin: 0 auto;
}

/* 一轉＝整欄的主角（.famhead 之後緊接著的那張就是 Lv10 起手職業） */
#app:has(> .jtree) .famcol > .famhead + .jcard {
  position: relative;
  flex-direction: column; align-items: center; text-align: center;
  gap: 1px;
  padding: 14px 12px 14px;
  border-radius: var(--rad-md); border-width: 1.5px;
  border-color: var(--wood-border);
  border-color: color-mix(in srgb, var(--fc) 34%, var(--wood-border));
  background: linear-gradient(180deg, var(--card) 0%, var(--card-wood) 100%);
  box-shadow: var(--e1), var(--rim);
}
/* 精靈圖的舞台，跟怪物圖鑑 .dex .sp 同一套語言 */
#app:has(> .jtree) .famcol > .famhead + .jcard::before {
  content: "";
  position: absolute; left: 10px; right: 10px; top: 10px; height: 104px;
  border-radius: var(--rad-md);
  border: 1px solid rgba(184, 154, 118, .2);
  background:
    radial-gradient(56% 44% at 50% 86%, rgba(130, 92, 50, .18) 0%, transparent 72%),
    linear-gradient(170deg, var(--bg-paper) 0%, #f8eee0 100%);
  background:
    radial-gradient(56% 44% at 50% 86%, rgba(130, 92, 50, .18) 0%, transparent 72%),
    linear-gradient(170deg, color-mix(in srgb, var(--fc) 9%, var(--bg-paper)) 0%, #f7ecdd 100%);
}
#app:has(> .jtree) .famcol > .famhead + .jcard .janim {
  --z: .56;
  position: relative; z-index: 1;
  margin: 0 0 4px;
  filter: drop-shadow(0 4px 6px rgba(90, 60, 25, .24));
  transition: transform var(--dur-3) var(--ease);
}
#app:has(> .jtree) .famcol > .famhead + .jcard:hover .janim { transform: translateY(-4px); }
#app:has(> .jtree) .famcol > .famhead + .jcard .jt { position: relative; z-index: 1; min-width: 0; max-width: 100%; }
#app:has(> .jtree) .famcol > .famhead + .jcard .n { font-size: var(--fs-sm); letter-spacing: -.01em; }
#app:has(> .jtree) .famcol > .famhead + .jcard .s { font-size: var(--fs-3xs); }
#app:has(> .jtree) .famcol > .famhead + .jcard:hover {
  transform: translateY(-4px);
  box-shadow: var(--e3), var(--rim);
  border-color: var(--fc);
}

/* Lv30 岔路：原本是一條 2px 的淡線，看不出「這裡要做第二次選擇」 */
#app:has(> .jtree) .famarrow {
  height: auto;
  display: flex; align-items: center; gap: 9px;
  margin: 6px 0 0;
}
#app:has(> .jtree) .famarrow::before {
  content: "Lv30 選一條路";
  position: static; width: auto; height: auto; opacity: 1;
  flex: 0 0 auto;
  padding: 4px 10px; border-radius: var(--rad-pill);
  font: 800 11px/1 Nunito, "Noto Sans TC", sans-serif; letter-spacing: .03em;
  white-space: nowrap;
  color: var(--text-brown); background: #f6ece0;
  border: 1px solid var(--line-strong);
  color: color-mix(in srgb, var(--fc) 72%, #3a2410);
  background: color-mix(in srgb, var(--fc) 13%, var(--card-parchment));
  border-color: color-mix(in srgb, var(--fc) 38%, transparent);
}
#app:has(> .jtree) .famarrow::after {
  content: "";
  flex: 1 1 auto; height: 1px;
  background: linear-gradient(90deg, var(--line-strong), transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--fc) 46%, transparent), transparent);
}

/* 二轉分支：緊湊列，精靈圖也有自己的小舞台 */
#app:has(> .jtree) .famcol > .famarrow ~ .jcard {
  position: relative;
  padding: 9px 12px 9px 9px;
  gap: 11px;
  border-radius: var(--rad-md); border-width: 1.5px;
  background: var(--card-parchment);
  box-shadow: var(--e1), var(--rim);
}
#app:has(> .jtree) .famcol > .famarrow ~ .jcard::before {
  content: "";
  position: absolute; left: 8px; top: 7px; bottom: 7px; width: 50px;
  border-radius: var(--rad-md);
  border: 1px solid rgba(184, 154, 118, .18);
  background:
    radial-gradient(58% 46% at 50% 86%, rgba(130, 92, 50, .15) 0%, transparent 72%),
    linear-gradient(170deg, var(--bg-paper) 0%, var(--card-wood) 100%);
}
#app:has(> .jtree) .famcol > .famarrow ~ .jcard .janim {
  --z: .36;
  position: relative; z-index: 1;
  margin: -6px 0;
  filter: drop-shadow(0 2px 3px rgba(90, 60, 25, .2));
  transition: transform var(--dur-3) var(--ease);
}
#app:has(> .jtree) .famcol > .famarrow ~ .jcard:hover .janim { transform: translateY(-3px); }
#app:has(> .jtree) .famcol > .famarrow ~ .jcard .jt { position: relative; z-index: 1; min-width: 0; }
#app:has(> .jtree) .famcol > .famarrow ~ .jcard:hover {
  transform: translateY(-3px);
  box-shadow: var(--e2), var(--rim);
  border-color: var(--fc);
}

/* 「6 招」被折到第二行是原本最醒目的破綻 —— 一行放不下就省略，不要換行。
   ⚠️ .jt 一定要 flex:1 + min-width:0，否則它只會取 max-content 的寬度，
      剩下的空間空著，字卻被 ellipsis 吃掉（第一版就是這樣把「招」切掉的）。*/
#app:has(> .jtree) .jcard .jt { flex: 1 1 auto; min-width: 0; }
#app:has(> .jtree) .jcard .n,
#app:has(> .jtree) .jcard .s {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
#app:has(> .jtree) .famcol > .famarrow ~ .jcard .n { font-size: var(--fs-xs); }
/* ⚠️ 量過：1440 時這行只有 107.7px 可用、字剛好 108px —— 差 1px 就會被 ellipsis
      把「招」吃掉。字級一定要留餘裕，不能照 style.css 的 12px。*/
#app:has(> .jtree) .famcol > .famarrow ~ .jcard .s { font-size: var(--fs-3xs); letter-spacing: -.01em; }
/* enhance.css 的 .jt:hover 位移會跟卡片自己的浮起打架 */
#app:has(> .jtree) .jcard .jt:hover { transform: none; box-shadow: none; }

/* 本季未開的三轉 / 四轉：沉到每一欄最底，五欄切齊 */
#app:has(> .jtree) .famlater {
  margin-top: auto;
  padding-top: 11px;
  border-top: 1px dashed var(--line-strong);
}
#app:has(> .jtree) .famlater > summary {
  list-style: none;
  padding: 7px 11px; border-radius: var(--rad-md);
  font-size: var(--fs-3xs); line-height: 1.6; font-weight: 800;
  color: var(--muted-brown);
  background: rgba(184, 154, 118, .11);
  text-wrap: balance;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
#app:has(> .jtree) .famlater > summary::-webkit-details-marker { display: none; }
#app:has(> .jtree) .famlater > summary::before {
  content: "🔒"; margin-right: 5px; font-size: var(--fs-3xs); filter: grayscale(1); opacity: .6;
}
#app:has(> .jtree) .famlater > summary:hover { background: rgba(230, 81, 0, .1); color: var(--accent-text); }
#app:has(> .jtree) .famlater .jcard {
  margin-top: 8px; padding: 7px 10px; gap: 9px; border-radius: var(--rad-md);
  background: rgba(255, 253, 248, .7);
}
#app:has(> .jtree) .famlater .jcard .janim { --z: .3; margin: -6px 0; }
#app:has(> .jtree) .famlater .jcard .jemb { width: 28px; height: 28px; }
#app:has(> .jtree) .famlater .jcard .n { font-size: var(--fs-2xs); }
#app:has(> .jtree) .famlater .jcard .s { font-size: var(--fs-3xs); }

/* ── 五大職業導讀：職業樹回答「有哪些」，這一段回答「打起來是什麼感覺」 ── */
#app:has(> .jtree) .famslide {
  padding: 28px 30px 24px;
  border-radius: var(--rad-lg); border-width: 1.5px;
  background: linear-gradient(180deg, var(--bg-paper) 0%, var(--card-parchment) 100%);
  box-shadow: var(--e2), var(--rim);
}
/* 左欄是家族海報、右欄是讀的內容 —— 原本整條橫的，右邊四成是空的 */
/* ⚠️ 這裡刻意用 float 而不是 grid：.fs-track 是 flex，五張 slide 會被最高的那張撐成等高，
      grid 會把撐出來的高度分給空的 row，中間裂出幾百 px 的空白（試過兩次都是這樣爆的）。
      float 是最老派也最穩的雜誌排版：左邊海報、右邊文字自己繞。*/
#app:has(> .jtree) .fs-slide { display: block; }
#app:has(> .jtree) .fs-slide::after { content: ""; display: block; clear: both; }
#app:has(> .jtree) .fs-slide > header {
  float: left; width: 248px; margin: 0 32px 14px 0;
  position: relative;
  display: grid; grid-template-columns: 1fr; justify-items: center;
  gap: 3px; text-align: center;
  margin: 0; padding: 24px 18px 20px;
  border: 1px solid var(--line); border-radius: var(--rad-lg);
  background: linear-gradient(180deg, var(--card-wood) 0%, var(--bg-paper) 74%);
  background: linear-gradient(180deg, color-mix(in srgb, var(--fc) 22%, var(--bg-paper)) 0%, var(--bg-paper) 74%);
  box-shadow: var(--e1), var(--rim);
}
#app:has(> .jtree) .fs-slide > header::after {
  content: "";
  grid-row: 1; grid-column: 1; align-self: end; justify-self: center;
  width: 108px; height: 20px; border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(110, 75, 40, .26) 0%, transparent 72%);
}
#app:has(> .jtree) .fs-slide > header .fportrait {
  position: relative; z-index: 1;
  grid-row: 1; grid-column: 1;
  width: 122px; max-height: 136px; flex: none;
  filter: drop-shadow(0 6px 11px rgba(90, 60, 25, .28));
}
#app:has(> .jtree) .fs-slide > header > div { margin-top: 8px; }
#app:has(> .jtree) .fs-slide > p:first-of-type { margin-top: 2px; font-size: var(--fs-sm); }
#app:has(> .jtree) .fs-slide > header h3 {
  font-size: var(--fs-lg); font-weight: 900; letter-spacing: -.01em;
  color: var(--text-title);
  color: color-mix(in srgb, var(--fc) 62%, #2a1708);
}
#app:has(> .jtree) .fs-slide > header p { color: var(--muted-brown); font-size: var(--fs-2xs); font-weight: 700; }
/* ⚠️ max-width 在 float 版型是陷阱：它量的是整個 block 的寬（含被 float 佔走的 248px），
      所以 72ch 的段落實際只剩 360px 能排字。要拿掉，行長交給 float 後的剩餘寬度決定。*/
#app:has(> .jtree) .fs-slide > p {
  max-width: none;
  font-size: var(--fs-xs); line-height: 1.95; color: var(--text-brown); margin: 0 0 12px;
}
#app:has(> .jtree) .fs-slide > p:last-child { margin-bottom: 0; }
#app:has(> .jtree) .fs-nav { box-shadow: var(--e1); }

/* ═══════════════════════════════════════════════════════════════════════════
   💇 外觀頁 —— 使用者來這頁是要「看自己換上去長怎樣」，不是讀一份髮型清單
   ─────────────────────────────────────────────────────────────────────────
   原本：一個髮型一張滿版白面板往下疊，八顆頭只用掉 1440 裡的 640，右邊六成全空；
         而且要比較兩個髮型得上下捲。試穿面板捲一下就不見了 —— 試衣間沒有鏡子。
   主張：這頁是試衣間。
     ① 桌機切兩欄：左邊型錄、右邊「試衣間」整個黏住（捲到哪都看得到自己）
     ② 髮型不再是一列一面板，改成一個髮型一張色票卡，多張並排 → 真的能比較
     ③ 每一格都站上舞台（漸層底 + 腳下投影），跟怪物圖鑑同一套語言
   ═══════════════════════════════════════════════════════════════════════════ */

:is(#app, #app > .legacy-host):has(> #lookbody) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  column-gap: 26px;
  align-items: start;
}
:is(#app, #app > .legacy-host):has(> #lookbody) > h1       { grid-column: 1; grid-row: 1; }
:is(#app, #app > .legacy-host):has(> #lookbody) > .sub     { grid-column: 1; grid-row: 2; }
/* 「這一套要花多少」排在篩選列之前：它是這一頁的答案，捲到最底才看到等於沒有。
   ⚠️ 這個 grid 把每一列都寫死，所以**新增子元素一定要在這裡配位置** ——
   沒配的會被自動塞到最後一列（型錄下面好幾個螢幕高的地方）而且完全不會報錯。 */
/* ⚠️ 2026-10-05：#collab 與 .lookmenu 當初沒配位置，被自動塞到型錄下面
   好幾個螢幕高的地方 —— 就是上面那行警告講的狀況，而且完全沒有徵兆。
   限定區塊要在最上面（它是這一頁現在最想被看到的東西）。 */
:is(#app, #app > .legacy-host):has(> #lookbody) > #lookcost{ grid-column: 1; grid-row: 3; min-width: 0; overflow-anchor: none; }
:is(#app, #app > .legacy-host):has(> #lookbody) > .lookmenu{ grid-column: 1; grid-row: 4; min-width: 0; }
:is(#app, #app > .legacy-host):has(> #lookbody) > .filters { grid-column: 1; grid-row: 5; }
/* 限定與型錄共用同一列 —— 同時只會顯示一個（syncG 切 display） */
:is(#app, #app > .legacy-host):has(> #lookbody) > #collab  { grid-column: 1; grid-row: 6; min-width: 0; }
:is(#app, #app > .legacy-host):has(> #lookbody) > #lookbody{ grid-column: 1; grid-row: 6; min-width: 0; }
:is(#app, #app > .legacy-host):has(> #lookbody) > #tryon {
  grid-column: 2; grid-row: 1 / span 6;
  align-self: start;
  position: sticky; top: calc(var(--top-h, 72px) + 16px);
  min-width: 0;
  overflow-anchor: none;
}

/* 型錄：一個髮型一張卡，並排比較 */
#app:has(#lookbody) #lookbody {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(298px, 1fr));
  gap: 16px;
  align-items: start;
}
#app:has(#lookbody) #lookbody > .lookrow { margin-bottom: 0; min-width: 0; }
/* 時裝（.lookgrid）與臉型 / 膚色是整排展櫃，不切欄 */
#app:has(#lookbody) #lookbody > .lookrow:has(.lookgrid),
#app:has(#lookbody) #lookbody > .lookgrid,
#app:has(#lookbody) #lookbody > .empty { grid-column: 1 / -1; }

#app:has(#lookbody) .lookrow {
  padding: 15px 16px 16px;
  border-width: 1.5px; border-radius: var(--rad-lg);
  background: linear-gradient(180deg, var(--bg-paper) 0%, var(--card-parchment) 100%);
  box-shadow: var(--e1), var(--rim);
  transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
#app:has(#lookbody) .lookrow:hover {
  transform: translateY(-3px);
  box-shadow: var(--e3), var(--rim);
  border-color: var(--wood-border-dark);
}
#app:has(#lookbody) .lr-h {
  align-items: center; gap: 9px;
  margin-bottom: 11px; padding-bottom: 9px;
  border-bottom: 1px solid var(--line);
}
#app:has(#lookbody) .lr-h b { font-size: var(--fs-sm); }
#app:has(#lookbody) .lr-h small {
  margin-left: auto;
  padding: 3px 9px; border-radius: var(--rad-pill);
  font-size: var(--fs-3xs); font-weight: 800; color: var(--muted-brown);
  background: rgba(184, 154, 118, .14);
  border: 1px solid var(--line);
}
/* 八個顏色躺成一條 4×2 的色帶，一眼比得出差別 */
#app:has(#lookbody) .lookrow .lr-c {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px;
}
#app:has(#lookbody) .lookrow .lr-c .lookcell { padding: 9px 4px 8px; border-radius: var(--rad-md); }
#app:has(#lookbody) .lookrow .lr-c .lookcell img { width: 54px; height: 54px; }
#app:has(#lookbody) .lookrow .lr-c .lookcell figcaption { font-size: var(--fs-3xs); margin-top: 4px; }
/* 只有一色的髮型佔一格會空掉四分之三 → 橫躺成整排，看起來才是刻意的 */
#app:has(#lookbody) .lookrow .lr-c > .lookcell:only-child {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: center; gap: 16px;
  padding: 10px 14px;
}
/* layout.css 給 .lookcell img 的 margin:0 auto 會把橫躺的那張圖推開 → 要歸零才置中 */
#app:has(#lookbody) .lookrow .lr-c > .lookcell:only-child img { margin: 0; }
#app:has(#lookbody) .lookrow .lr-c > .lookcell:only-child figcaption { margin-top: 0; }

/* 每一格都是一個小舞台 */
#app:has(#lookbody) .lookcell {
  position: relative;
  border-width: 1.5px;
  background:
    radial-gradient(58% 42% at 50% 84%, rgba(130, 92, 50, .14) 0%, transparent 70%),
    radial-gradient(circle at 50% 32%, var(--card) 24%, var(--paper-edge) 100%);
  box-shadow: var(--e1), var(--rim);
}
#app:has(#lookbody) .lookcell::after {
  content: "";
  position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(120deg, var(--gloss) 0%, transparent 44%);
}
#app:has(#lookbody) .lookcell img {
  position: relative; z-index: 1;
  filter: drop-shadow(0 2px 3px rgba(90, 60, 25, .22));
  transition: transform var(--dur-2) var(--ease);
}
#app:has(#lookbody) .lookcell:hover img { transform: translateY(-2px) scale(1.05); }
#app:has(#lookbody) .lookcell:hover { box-shadow: var(--e2), var(--rim); }
#app:has(#lookbody) .lookcell figcaption { position: relative; z-index: 1; }
#app:has(#lookbody) .lookcell.on { box-shadow: 0 0 0 2px var(--accent-orange), var(--e2); outline: none; }

/* 時裝：整身立繪值得更大的展櫃 */
#app:has(#lookbody) .lookrow:has(.lookgrid) .lookgrid,
#app:has(#lookbody) #lookbody > .lookgrid {
  grid-template-columns: repeat(auto-fill, minmax(122px, 1fr));
  gap: 13px;
}
#app:has(#lookbody) .lookcell.body { padding: 12px 8px 11px; }
#app:has(#lookbody) .lookcell.body img { width: 80px; height: 104px; }
#app:has(#lookbody) .lookcell.big img { width: 70px; height: 70px; }
#app:has(#lookbody) .lookcell .dia { display: flex; width: fit-content; margin: 6px auto 0; }

/* ── 試衣間：捲到哪都黏著，永遠看得到自己 ── */
#app:has(#lookbody) #tryon .panel.tryon {
  display: flex; flex-direction: column; align-items: stretch;
  gap: 0; margin: 0; padding: 0 0 4px;
  overflow: hidden;
  border-width: 1.5px; border-radius: var(--rad-lg);
  background: linear-gradient(180deg, var(--bg-paper) 0%, var(--card-parchment) 100%);
  box-shadow: var(--e2), var(--rim);
}
#app:has(#lookbody) #tryon .panel.tryon::before {
  content: "試衣間";
  display: block;
  padding: 12px 16px;
  font: 900 14px/1 Nunito, "Noto Sans TC", sans-serif; letter-spacing: .02em;
  color: var(--text-title);
  background: linear-gradient(180deg, var(--tint-warm) 0%, var(--tint-warm) 100%);
  border-bottom: 1px solid var(--line);
}
/* 紙娃娃：登入後的鏡子 */
#app:has(#lookbody) #tryon .tryon-doll {
  width: auto; flex: none;
  margin: 14px 16px 0; padding: 14px;
  height: 208px; min-height: 208px; border-radius: var(--rad-md);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  border: 1px solid var(--line);
  background:
    radial-gradient(58% 34% at 50% 88%, rgba(130, 92, 50, .17) 0%, transparent 70%),
    radial-gradient(circle at 50% 30%, var(--card) 26%, var(--paper-edge) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9);
}
#app:has(#lookbody) #tryon .tryon-doll img {
  display: block; margin: auto; max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain;
  filter: drop-shadow(0 4px 7px rgba(90, 60, 25, .26));
}
#app:has(#lookbody) #tryon .tryon-side { flex: 1 1 auto; min-width: 0; padding: 14px 16px 12px; }
#app:has(#lookbody) #tryon .tryon-side h3 { font-size: var(--fs-xs); }
#app:has(#lookbody) #tryon .tryon-side h3 small { display: block; margin-top: 3px; font-weight: 600; }
#app:has(#lookbody) #tryon .tryon-act { margin: 12px 0 8px; }
#app:has(#lookbody) #tryon .tryon-side .muted { font-size: var(--fs-2xs); line-height: 1.75; }

/* 還沒登入：不要留一條空白橫槓，給一個「這裡會站著你的角色」的人形待機位 */
#app:has(#lookbody) #tryon .tryon-empty {
  display: block; text-align: center;
  padding: 0 16px 18px;
  font-size: var(--fs-2xs); line-height: 1.8; font-weight: 700; color: var(--muted-brown);
}
#app:has(#lookbody) #tryon .tryon-empty::before {
  content: "";
  display: block; height: 186px; margin: 14px 0 14px;
  border-radius: var(--rad-md); border: 1px dashed var(--line-strong);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 112'%3E%3Cg fill='none' stroke='%23b89a74' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round' stroke-dasharray='7 8'%3E%3Ccircle cx='40' cy='20' r='13'/%3E%3Cpath d='M40 35v40M40 45L21 57M40 45l19 12M40 75L28 103M40 75l12 28'/%3E%3C/g%3E%3C/svg%3E") center 22px / auto 132px no-repeat,
    radial-gradient(58% 30% at 50% 86%, rgba(130, 92, 50, .14) 0%, transparent 70%),
    radial-gradient(circle at 50% 30%, var(--card) 28%, var(--card-wood) 100%);
}
/* 文字與按鈕原本是同一個 flex 行 → 按鈕會卡在句子中間。讓它自己站一行。 */
#app:has(#lookbody) #tryon .tryon-empty .auth-btn {
  display: flex; width: fit-content; margin: 14px auto 0; padding: 10px 20px;
}

/* 篩選列在窄的主欄裡要換行，不要被擠爆 */
#app:has(#lookbody) .filters { margin: 12px 0 18px; }
#app:has(#lookbody) .filters input[type=search] { flex: 1 1 180px; min-width: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   📺 探險實況 —— 使用者來這頁是要「看現在有誰在玩、他在幹嘛」
   ─────────────────────────────────────────────────────────────────────────
   原本：一塊 130px 高的暗色方塊，寫一行「目前沒有人在掛機。」，
         底下 700px 全白 —— 整頁看起來像壞掉，而且沒告訴人怎麼讓自己出現在這裡。
   主張：這頁是轉播室。
     ① livebox 變成真的播放器機殼：轉播列（HUD）／舞台（canvas）／頻道清單
     ② 正在掛機的玩家＝頻道卡，並排、可 hover、點了就進轉播
     ③ 沒人掛機不是一行灰字，是一塊「待機畫面」，並寫出怎麼開播
   ═══════════════════════════════════════════════════════════════════════════ */

#app:has(> .legacy-host > .livebox) .sub kbd {
  display: inline-block; padding: 2px 8px; margin: 0 1px;
  border-radius: var(--rad-sm); border: 1px solid var(--line-strong); border-bottom-width: 2px;
  background: var(--bg-paper); color: var(--text-brown);
  font: 800 12px/1.5 Nunito, monospace;
  box-shadow: var(--e1);
}

#app:has(> .legacy-host > .livebox) .livebox {
  position: relative;
  display: flex; flex-direction: column;
  min-height: 564px;
  margin-top: 16px; padding: 0;
  border-radius: var(--rad-lg);
  border: 1px solid rgba(255, 255, 255, .08);
  background:
    radial-gradient(120% 88% at 50% -12%, #1d2739 0%, #131926 52%, #0b0e16 100%);
  box-shadow:
    0 4px 10px rgba(20, 12, 4, .1),
    0 28px 68px rgba(20, 12, 4, .26),
    inset 0 1px 0 rgba(255, 255, 255, .07);
  overflow: hidden;
}
/* 有頻道卡時不要撐 564 —— 四張卡下面會留一大塊沒有用的黑。
   待機畫面與轉播中才需要那個高度。*/
#app:has(> .legacy-host > .livebox) .livebox:has(#list > a) { min-height: 0; }
/* 機殼上緣的一道暖光，讓暗盒子不是硬貼在羊皮紙上 */
#app:has(> .legacy-host > .livebox) .livebox::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(242, 101, 34, .65) 22%, rgba(255, 196, 120, .5) 52%, transparent);
}

/* 轉播列 */
#app:has(> .legacy-host > .livebox) .livebox #hud {
  align-items: center;
  gap: 8px 18px;
  padding: 15px 22px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  background: linear-gradient(180deg, rgba(255, 255, 255, .05) 0%, transparent 100%);
}
#app:has(> .legacy-host > .livebox) .livebox #hud b {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: var(--fs-sm); letter-spacing: .01em;
}
#app:has(> .legacy-host > .livebox) .livebox #hud b::before {
  content: "";
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: #ff4d4d;
  box-shadow: 0 0 0 0 rgba(255, 77, 77, .55), 0 0 10px rgba(255, 77, 77, .8);
  animation: liveDot 2.4s var(--ease) infinite;
}
@keyframes liveDot {
  70%  { box-shadow: 0 0 0 9px rgba(255, 77, 77, 0), 0 0 10px rgba(255, 77, 77, .8); }
  100% { box-shadow: 0 0 0 0 rgba(255, 77, 77, 0), 0 0 10px rgba(255, 77, 77, .8); }
}
#app:has(> .legacy-host > .livebox) .livebox #hud .st {
  padding: 3px 11px; border-radius: var(--rad-pill);
  background: rgba(242, 101, 34, .18);
  border: 1px solid rgba(242, 101, 34, .4);
  color: #ffc89a; font-weight: 800;
}
#app:has(> .legacy-host > .livebox) .livebox #hud .muted { color: #8794a9; }
#app:has(> .legacy-host > .livebox) .livebox #roster b { color: #f2f5fa; }

/* 舞台 */
#app:has(> .legacy-host > .livebox) .livebox > canvas {
  width: auto; align-self: stretch;
  margin: 18px 22px 2px;
  border-radius: var(--rad-md);
  background: #0d1320;
  box-shadow: 0 16px 38px rgba(0, 0, 0, .45), inset 0 0 0 1px rgba(255, 255, 255, .06);
}

/* 頻道清單 */
#app:has(> .legacy-host > .livebox) .livebox #list {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
  gap: 12px;
  flex: 1 1 auto;
  margin: 0; padding: 18px 22px 22px;
  align-content: start;
}
#app:has(> .legacy-host > .livebox) .livebox #list a {
  display: flex; flex-direction: column; gap: 5px;
  margin: 0; padding: 15px 17px;
  border-radius: var(--rad-md);
  border: 1px solid rgba(255, 255, 255, .09);
  background: linear-gradient(180deg, rgba(255, 255, 255, .06) 0%, rgba(255, 255, 255, .018) 100%);
  transition: transform var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
#app:has(> .legacy-host > .livebox) .livebox #list a::before {
  content: "▶ 進入轉播";
  order: 2;
  font-size: var(--fs-3xs); font-weight: 800; letter-spacing: .04em;
  color: #ff9a5c;
  opacity: .55; transition: opacity var(--dur-2) var(--ease);
}
#app:has(> .legacy-host > .livebox) .livebox #list a:hover {
  transform: translateY(-3px);
  background: rgba(255, 255, 255, .085);
  border-color: rgba(242, 101, 34, .5);
  box-shadow: 0 14px 30px rgba(0, 0, 0, .38);
}
#app:has(> .legacy-host > .livebox) .livebox #list a:hover::before { opacity: 1; }
#app:has(> .legacy-host > .livebox) .livebox #list a b { color: var(--on-solid); font-size: var(--fs-sm); letter-spacing: -.01em; }
#app:has(> .legacy-host > .livebox) .livebox #list a .muted { color: #8f9bb0; font-size: var(--fs-2xs); line-height: 1.7; }
/* 挑戰者服：左側三行（ID／Lv·職業／地點），右側 3 倍大頭；「進入轉播」貼在大頭正下方 */
#app:has(> .legacy-host > .livebox) .livebox #list .lv-main { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
#app:has(> .legacy-host > .livebox) .livebox #list .lv-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
#app:has(> .legacy-host > .livebox) .livebox #list .lv-head { width: 72px; height: 72px; flex: 0 0 72px; image-rendering: pixelated; }
#app:has(> .legacy-host > .livebox) .livebox #list a::before { align-self: flex-end; }

/* 待機畫面：沒人開播時，這裡是整頁唯一的內容，不能只留一行灰字 */
/* 沒有節目時待機畫面要撐滿整個機殼 —— 不然下面會留一大塊沒有意義的黑 */
#app:has(> .legacy-host > .livebox) .livebox #list:has(> p.muted) { align-content: stretch; }
#app:has(> .legacy-host > .livebox) .livebox #list > p.muted,
#app:has(> .legacy-host > .livebox) .livebox .empty {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  margin: 0; padding: 40px 28px;
  text-align: center;
  border-radius: var(--rad-lg);
  border: 1px dashed rgba(255, 255, 255, .15);
  color: #9aa6ba; font-size: var(--fs-sm); font-weight: 800; line-height: 1.7;
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .022) 0 12px, transparent 12px 24px),
    radial-gradient(64% 74% at 50% 38%, rgba(92, 124, 176, .16) 0%, transparent 72%);
}
#app:has(> .legacy-host > .livebox) .livebox #list > p.muted::before,
#app:has(> .legacy-host > .livebox) .livebox .empty::before {
  content: "";
  display: block; width: 88px; height: 88px; margin: 0 auto 20px;
  border-radius: var(--rad-lg);
  border: 2px solid rgba(255, 255, 255, .16);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23a9b6cb' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2.5' y='7' width='19' height='13' rx='2.5'/%3E%3Cpath d='M8 3.5l4 3.5 4-3.5'/%3E%3Cpath d='M10.5 11.4v4.2l4-2.1z' fill='%23a9b6cb' stroke='none'/%3E%3C/g%3E%3C/svg%3E") center / 44px no-repeat,
    rgba(255, 255, 255, .04);
}
#app:has(> .legacy-host > .livebox) .livebox #list > p.muted::after,
#app:has(> .legacy-host > .livebox) .livebox .empty::after {
  content: "在 Discord 打 /探險 開始掛機 —— 結算時會錄下 60 秒走位，你的角色就會出現在這裡。";
  display: block; max-width: 36ch; margin: 12px auto 0;
  font-size: var(--fs-2xs); font-weight: 600; line-height: 1.95; color: #7c8798;
}

} /* @media (min-width: 1024px) */

/* ── 無障礙：關掉動態時不靠動畫顯示任何東西（上面沒有 opacity:0 的起始狀態，
      這裡只把會持續跑的脈動關掉，內容一律維持可見）────────────────────── */
@media (prefers-reduced-motion: reduce) {
  #app:has(> .legacy-host > .livebox) .livebox #hud b::before { animation: none; }
  #app:has(> .legacy-host > .livebox) .livebox #list a::before { opacity: 1; }
}

/* 大螢幕：試衣間可以寬一點，型錄也放得下第三欄 */
@media (min-width: 1360px) {
  :is(#app, #app > .legacy-host):has(> #lookbody) { grid-template-columns: minmax(0, 1fr) 324px; column-gap: 28px; }
}
/* 中型桌機／平板橫向（769~1023px）：一樣固定右側試衣間，不讓往下滑動時人物預覽跑掉 */
@media (min-width: 769px) and (max-width: 1023px) {
  :is(#app, #app > .legacy-host):has(> #lookbody) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 268px;
    column-gap: 20px;
    align-items: start;
  }
  :is(#app, #app > .legacy-host):has(> #lookbody) > h1       { grid-column: 1; grid-row: 1; }
  :is(#app, #app > .legacy-host):has(> #lookbody) > .sub     { grid-column: 1; grid-row: 2; }
  :is(#app, #app > .legacy-host):has(> #lookbody) > #lookcost{ grid-column: 1; grid-row: 3; min-width: 0; }
  :is(#app, #app > .legacy-host):has(> #lookbody) > .lookmenu{ grid-column: 1; grid-row: 4; min-width: 0; }
  :is(#app, #app > .legacy-host):has(> #lookbody) > .filters { grid-column: 1; grid-row: 5; }
  :is(#app, #app > .legacy-host):has(> #lookbody) > #collab  { grid-column: 1; grid-row: 6; min-width: 0; }
  :is(#app, #app > .legacy-host):has(> #lookbody) > #lookbody{ grid-column: 1; grid-row: 6; min-width: 0; }
  :is(#app, #app > .legacy-host):has(> #lookbody) > #tryon {
    grid-column: 2; grid-row: 1 / span 6;
    align-self: start;
    position: sticky; top: calc(var(--top-h, 72px) + 12px);
    min-width: 0;
  }
  #app:has(#lookbody) #tryon .panel.tryon {
    display: flex; flex-direction: column; align-items: stretch;
    gap: 0; margin: 0; padding: 0 0 4px;
    overflow: hidden;
    border-width: 1.5px; border-radius: var(--rad-lg);
    background: linear-gradient(180deg, var(--bg-paper) 0%, var(--card-parchment) 100%);
    box-shadow: var(--e2), var(--rim);
  }
  #app:has(#lookbody) #tryon .panel.tryon::before {
    content: "試衣間";
    display: block; padding: 12px 16px;
    font: 900 14px/1 Nunito, "Noto Sans TC", sans-serif; letter-spacing: .02em;
    color: var(--text-title);
    background: linear-gradient(180deg, var(--tint-warm) 0%, var(--tint-warm) 100%);
    border-bottom: 1px solid var(--line);
  }
  #app:has(#lookbody) #tryon .tryon-doll {
    width: auto; flex: none; margin: 14px 16px 0; padding: 14px;
    height: 186px; min-height: 186px; border-radius: var(--rad-md); border: 1px solid var(--line);
    display: flex; align-items: center; justify-content: center; overflow: hidden;
    background:
      radial-gradient(58% 34% at 50% 88%, rgba(130, 92, 50, .17) 0%, transparent 70%),
      radial-gradient(circle at 50% 30%, var(--card) 26%, var(--paper-edge) 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9);
  }
  #app:has(#lookbody) #tryon .tryon-doll img {
    display: block; margin: auto; max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain;
  }
  #app:has(#lookbody) #tryon .tryon-side { flex: 1 1 auto; min-width: 0; padding: 14px 16px 12px; }
  #app:has(#lookbody) #tryon .tryon-empty { display: block; text-align: center; padding: 0 16px 18px; }
  #app:has(#lookbody) #tryon .tryon-empty .auth-btn { display: flex; width: fit-content; margin: 14px auto 0; padding: 10px 20px; }
}

/* ── 1024~1279：五欄家族海報會擠到只剩 180px，精靈圖與字級要一起收 ─────────── */
@media (min-width: 1024px) and (max-width: 1279px) {
  #app:has(> .jtree) .jtree { gap: 10px; }
  #app:has(> .jtree) .famcol { padding: 12px; }
  #app:has(> .jtree) .famhead { margin: -12px -12px 4px; padding: 13px 10px 11px; }
  #app:has(> .jtree) .famhead .fportrait { width: 62px; max-height: 70px; }
  #app:has(> .jtree) .famhead::after { width: 66px; }
  #app:has(> .jtree) .famhead .fn { font-size: var(--fs-sm); }
  #app:has(> .jtree) .famhead .fs { font-size: var(--fs-3xs); }
  #app:has(> .jtree) .famcol > .famhead + .jcard { padding: 12px 8px; }
  #app:has(> .jtree) .famcol > .famhead + .jcard::before { left: 7px; right: 7px; height: 92px; }
  #app:has(> .jtree) .famcol > .famhead + .jcard .janim { --z: .5; }
  #app:has(> .jtree) .famcol > .famhead + .jcard .n { font-size: var(--fs-sm); }
  #app:has(> .jtree) .famarrow::before { font-size: var(--fs-3xs); padding: 3px 7px; }
  #app:has(> .jtree) .famcol > .famarrow ~ .jcard { padding: 8px 9px 8px 7px; gap: 8px; }
  #app:has(> .jtree) .famcol > .famarrow ~ .jcard::before { left: 6px; width: 42px; }
  #app:has(> .jtree) .famcol > .famarrow ~ .jcard .janim { --z: .3; }
  #app:has(> .jtree) .famcol > .famarrow ~ .jcard .n { font-size: var(--fs-2xs); }
  #app:has(> .jtree) .famcol > .famarrow ~ .jcard .s { font-size: var(--fs-3xs); letter-spacing: -.02em; }
  #app:has(> .jtree) .famcol > .famarrow ~ .jcard { padding-right: 8px; }
  #app:has(> .jtree) .famlater > summary { font-size: var(--fs-3xs); padding: 6px 8px; }
  /* 五大職業：窄螢幕不夠繞排，海報改回整排在上 */
  #app:has(> .jtree) .fs-slide > header { float: none; width: auto; max-width: 260px; margin: 0 auto 16px; }
  #app:has(> .jtree) .famslide { padding: 22px 22px 20px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   製作頁（#/craft）
   一張卡＝一個配方。重點是「要什麼材料、去哪打、找誰做」這三件事，
   所以材料列直接把來源寫在右邊，不用再點進去查。
   ═══════════════════════════════════════════════════════════════════════════ */
.cf-sec { margin: 34px 0 0; }
.cf-sec > h2 {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin: 0 0 14px; font-size: var(--fs-lg);
}
.cf-sec > h2 small { font-weight: 500; font-size: var(--fs-2xs); color: var(--muted); }
.cf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }

.cf-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--rad-md);
  padding: 16px 16px 14px; display: flex; flex-direction: column; gap: 11px;
  transition: border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}
.cf-card:hover { border-color: var(--accent-gold-light); box-shadow: var(--e2); transform: translateY(-2px); }
.cf-card > header { display: flex; align-items: center; gap: 12px; }
.cf-card h3 { margin: 0; font-size: var(--fs-sm); }
.cf-card h3 a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--line); }
.cf-card h3 a:hover { color: var(--accent-text); border-bottom-color: var(--accent); }
.cf-sub { margin: 2px 0 0; font-size: var(--fs-2xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.cf-ic {
  flex: none; width: 46px; height: 46px; display: grid; place-items: center;
  border-radius: var(--rad-md); background: rgba(184, 154, 118, .12); border: 1px solid var(--line);
}
.cf-ic img { max-width: 34px; max-height: 34px; image-rendering: pixelated; }
.cf-noic { font-size: var(--fs-md); }
.cf-desc { margin: 0; font-size: var(--fs-2xs); color: var(--muted); line-height: 1.7; }

.cf-mats { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
.cf-mats li {
  display: grid; grid-template-columns: 20px auto auto 1fr; align-items: center; gap: 4px 8px;
  padding: 5px 0; font-size: var(--fs-2xs); border-top: 1px dashed var(--line);
}
.cf-mats li[data-mat] { cursor: pointer; border-radius: var(--rad-sm); padding: 5px 4px; transition: background-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease); }
.cf-mats li[data-mat]:hover { background: rgba(184, 154, 118, .18); }
.cf-mats li[data-mat]:hover b { color: var(--accent-text); text-decoration: underline; }
.cf-costlist li[data-mat] { cursor: pointer; transition: background-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease); }
.cf-costlist li[data-mat]:hover b { color: var(--accent-text); text-decoration: underline; }
/* 只動 box-shadow（邊框色由 .cf-highlight 本身設定，動畫裡動 border-color 會觸發重繪） */
@keyframes cfHighlightPulse {
  0% { box-shadow: 0 0 0 0 rgba(230, 126, 34, .7); }
  50% { box-shadow: 0 0 0 8px rgba(230, 126, 34, 0); }
  100% { box-shadow: 0 0 0 0 rgba(230, 126, 34, 0); }
}
.cf-card.cf-highlight,
.cf-refine-card.cf-highlight {
  animation: cfHighlightPulse 1.8s ease-out;
  border-color: var(--accent) !important;
  background: rgba(184, 154, 118, .15) !important;
}
.cf-mats li:first-child { border-top: none; }
.cf-n { color: var(--accent-text); font-weight: 800; font-variant-numeric: tabular-nums; }
.cf-from { font-size: var(--fs-3xs); color: var(--muted); text-align: right; }
.cf-mi { width: 20px; height: 20px; object-fit: contain; image-rendering: pixelated; }
i.cf-mi { border-radius: var(--rad-sm); background: rgba(184, 154, 118, .16); }
.cf-who { font-size: var(--fs-2xs); color: var(--muted); border-top: 1px solid var(--line); padding-top: 9px; }
.cf-who b { color: var(--text-title); }
.cf-who small { margin-left: 4px; opacity: .75; }

.cf-npcs { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.cf-npc { background: var(--card); border: 1px solid var(--line); border-radius: var(--rad-md); padding: 12px 14px; }
.cf-npc b { font-size: var(--fs-xs); }
.cf-npc small { margin-left: 6px; font-size: var(--fs-3xs); color: var(--muted); }
.cf-npc p { margin: 6px 0 0; font-size: var(--fs-2xs); color: var(--muted); line-height: 1.7; }

/* 三步驟 / 熟練度說明 */
.cf-steps { margin: 0 0 12px; padding-left: 20px; display: grid; gap: 7px; font-size: var(--fs-2xs); line-height: 1.75; }
.cf-steps b { color: var(--accent-text); margin-right: 6px; }
.cf-note { margin: 0; font-size: var(--fs-2xs); color: var(--muted); line-height: 1.85; }
/* 師傅卡：點了會切配方 */
.cf-npc { cursor: pointer; transition: border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); }
.cf-npc:hover { border-color: var(--accent-gold-light); transform: translateY(-2px); }
.cf-npc.on { border-color: var(--accent); background: rgba(184, 154, 118, .12); }
.cf-npc i { font-style: normal; color: var(--accent-text); font-size: var(--fs-3xs); }
/* 配方搜尋與多選篩選列 */
.cf-bar { margin: 0 0 16px; display: flex; flex-direction: column; gap: 10px; }
.cf-filter-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cf-filter-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cf-filter-label { font-size: var(--fs-2xs); font-weight: 700; color: var(--muted); min-width: 56px; }
.cf-chips .chip small { font-size: var(--fs-3xs); opacity: 1; margin-left: 3px; font-variant-numeric: tabular-nums; }
.cf-bar input {
  width: 100%; max-width: 340px; padding: 9px 13px; font: inherit; font-size: var(--fs-xs);
  border: 1px solid var(--line); border-radius: var(--rad-md); background: var(--card); color: var(--text);
}
.cf-bar input:focus { outline: none; border-color: var(--accent); }
/* 熟練等級分段標題 */
.cf-lv { margin: 22px 0 10px; font-size: var(--fs-xs); color: var(--text-title); }
.cf-lv small { margin-left: 8px; font-weight: 500; font-size: var(--fs-2xs); color: var(--muted); }
/* 做不出來的配方：整張卡壓暗 */
.cf-card.off { opacity: .55; }
.cf-why { font-size: var(--fs-3xs); color: var(--muted); border-top: 1px solid var(--line); padding-top: 8px; }
/* 熟練度表 */
.cf-tbl { width: 100%; max-width: 460px; border-collapse: collapse; font-size: var(--fs-2xs); font-variant-numeric: tabular-nums; }
.cf-tbl th, .cf-tbl td { padding: 7px 12px; text-align: left; border-bottom: 1px solid var(--line); }
.cf-tbl th { color: var(--muted); font-weight: 600; font-size: var(--fs-2xs); }

.cf-locked { display: flex; flex-wrap: wrap; gap: 9px; }
.cf-lk {
  display: inline-flex; flex-direction: column; gap: 2px;
  padding: 8px 13px; border-radius: var(--rad-md); font-size: var(--fs-2xs);
  background: rgba(184, 154, 118, .09); border: 1px dashed var(--line); color: var(--muted);
}
.cf-lk small { font-size: var(--fs-3xs); opacity: .8; }

@media (max-width: 880px) {
  .cf-grid { grid-template-columns: 1fr; }
  /* 390px 放不下「材料 ×N　來源」三欄 → 來源換行靠左 */
  .cf-mats li { grid-template-columns: 20px auto auto; }
  .cf-from { grid-column: 1 / -1; text-align: left; }
  .cf-bar input { max-width: none; }
  .cf-filter-row { flex-direction: column; align-items: flex-start; gap: 6px; }
  .cf-tbl { max-width: none; }
  /* 熟練度表不在 .panel 裡，吃不到 mobile.css 第 8 節的放寬 → 被 style.css 的 table { min-width: 460px } 撐出
     390px 寬的橫向捲動（2026-10-14 截圖抓到）。三欄都是短數字，直接放開。 */
  .cf-tbl { min-width: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   背景音樂的浮動控制（bgm.js）
   收起來是一顆鈕，滑上去／播放中才把曲名攤開 —— 不搶內容的版面。
   ═══════════════════════════════════════════════════════════════════════════ */
.bgm {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  display: flex; align-items: center; gap: 0;
  padding: 6px; border-radius: var(--rad-pill);
  background: var(--card-parchment);
  border: 1px solid var(--line);
  box-shadow: var(--e2);
  /* 模糊拿掉：這顆是 position:fixed、永遠浮在畫面上，
     每一幀捲動都要重算背後的模糊；底色 92% 不透明，看不出差別。 */
  transition: gap var(--dur-2) var(--ease), padding var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.bgm:hover { box-shadow: var(--e3, 0 10px 30px rgba(92, 58, 20, .18)); }
.bgm button {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  border: none; background: transparent; cursor: pointer;
  display: grid; place-items: center; color: var(--text-title);
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease), transform var(--dur-1) var(--ease-spring);
}
.bgm button:hover { background: rgba(230, 81, 0, .1); color: var(--accent-text); }
.bgm button:active { transform: scale(.92); }
.bgm svg { width: 19px; height: 19px; fill: currentColor; }
.bgm-t { position: relative; }
.bgm .bgm-i-stop, .bgm.on .bgm-i-play { display: none; }
.bgm.on .bgm-i-stop { display: block; }

/* 曲名：預設收成 0 寬度，播放中或滑上去才展開 */
.bgm-meta {
  display: flex; flex-direction: column; justify-content: center;
  max-width: 0; overflow: hidden; white-space: nowrap;
  transition: max-width var(--dur-3) var(--ease), padding var(--dur-3) var(--ease), opacity var(--dur-2) var(--ease);
  opacity: 0; padding: 0;
}
.bgm:hover .bgm-meta, .bgm.on .bgm-meta { max-width: 150px; opacity: 1; padding: 0 4px 0 6px; }
.bgm-meta b { font-size: var(--fs-2xs); line-height: 1.25; color: var(--text-title); }
.bgm-meta small { font-size: var(--fs-3xs); color: var(--muted); letter-spacing: .03em; }
.bgm-next { display: none; }
.bgm:hover .bgm-next, .bgm.on .bgm-next { display: grid; }

/* 播放中：鈕上三根跳動的小柱 */
.bgm-eq { position: absolute; inset: 0; display: none; align-items: flex-end; justify-content: center; gap: 2px; padding-bottom: 11px; }
.bgm.on .bgm-eq { display: flex; }
.bgm.on .bgm-i-stop { opacity: 0; }          /* 停止圖示只在滑上去時換回來 */
.bgm.on .bgm-t:hover .bgm-eq { display: none; }
.bgm.on .bgm-t:hover .bgm-i-stop { opacity: 1; }
.bgm-eq i { width: 2.5px; border-radius: var(--rad-sm); background: var(--accent); animation: bgmEq .9s ease-in-out infinite; }
.bgm-eq i:nth-child(1) { height: 7px;  animation-delay: -.2s; }
.bgm-eq i:nth-child(2) { height: 13px; animation-delay: -.55s; }
.bgm-eq i:nth-child(3) { height: 9px;  animation-delay: -.85s; }
@keyframes bgmEq { 0%, 100% { transform: scaleY(.4); } 50% { transform: scaleY(1); } }

@media (max-width: 880px) {
  /* 手機：不要擋住內容底部，縮小一點、貼近邊角 */
  .bgm { right: 12px; bottom: 12px; padding: 5px; }
  .bgm button { width: 34px; height: 34px; }
  .bgm:hover .bgm-meta { max-width: 0; opacity: 0; padding: 0; }   /* 手機沒有 hover，別被誤觸展開 */
  .bgm.on .bgm-meta { max-width: 118px; opacity: 1; padding: 0 3px 0 5px; }
  .bgm:hover .bgm-next { display: none; }
  .bgm.on .bgm-next { display: grid; }
}
@media (prefers-reduced-motion: reduce) {
  .bgm-eq i { animation: none; }
  .bgm, .bgm-meta { transition: none; }
}

/* ═══ 排行榜裝備檢視（2026-10-03 重做）═══════════════════════════════════════
   原本這一區有三個東西是壞的，而且都不會報錯：
     · 裝備永遠空白（後端 isActive 判斷用了不存在的 char.id）
     · 圖示永遠 404（用存檔的 it_xxx 當檔名，但檔名是 WZ 數字 id）
     · 側寫每個人都一樣（參數傳反 + 本來就是沒有資訊量的形容詞）
   ═══════════════════════════════════════════════════════════════════════ */

/* 事實列：取代原本那句「在楓之谷世界踏實歷練的冒險者。」 */
.gear-facts { margin: var(--sp-3) 0 0; display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--rad-sm); overflow: hidden; }
.gear-facts > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); padding: 7px 11px; background: var(--card); }
.gear-facts dt { margin: 0; font-size: var(--fs-2xs); color: var(--muted-brown); font-weight: 700; }
.gear-facts dd { margin: 0; font-weight: 800; color: var(--text-title); font-variant-numeric: tabular-nums lining-nums; }
.gear-profile-comment { margin: var(--sp-3) 0 0; font-size: var(--fs-2xs); color: var(--muted-brown); line-height: 1.7; }

/* 沒有圖示的格子：畫一個空槽，不要留一塊塌掉的空白 */
.slot-icon-box.noicon::after,
.slot-icon-box:empty::after {
  content: ""; display: block; width: 26px; height: 26px; margin: 0 auto;
  border: 1.5px dashed var(--wood-border); border-radius: var(--rad-sm); opacity: .5;
}

/* 鍵盤焦點要看得出來 —— 這組格子現在方向鍵走得動 */
.equip-slot-cell:focus-visible { outline: 3px solid var(--accent-orange); outline-offset: 2px; }

/* 「這一身加起來」：逐件看回答不了的問題 */
.gear-totals { margin-top: var(--sp-4); border: 1.5px solid var(--wood-border); border-radius: var(--rad-md); background: var(--card-parchment); padding: var(--sp-4); }
.gear-totals h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-sm); color: var(--text-title); }
.gear-totals h3::before, .gear-totals h3::after { content: none; }
.gear-totals ul { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 6px; }
.gear-totals li { display: flex; justify-content: space-between; gap: 8px; background: var(--card); border: 1px solid var(--line); border-radius: var(--rad-sm); padding: 5px 9px; font-size: var(--fs-2xs); }
.gear-totals li b { font-variant-numeric: tabular-nums lining-nums; color: var(--accent-text); }
.gear-totals .muted { margin: var(--sp-3) 0 0; font-size: var(--fs-3xs); }

/* ═══ 衝卷模擬器（2026-10-03）═══════════════════════════════════════════════
   裝備頁本來 0 個可以點的東西。這是整頁唯一一個「會回答你問題」的區塊，
   所以版面要讓人一眼知道：選卷 → 跑 → 看分佈。 */
.scroll-lab .lab-row { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.scroll-lab label { font-weight: 800; font-size: var(--fs-2xs); color: var(--muted-brown); min-width: 4.5em; }
.scroll-lab select { flex: 1 1 260px; max-width: 100%; padding: 7px 10px; border: 1.5px solid var(--wood-border); border-radius: var(--rad-sm); background: var(--card); color: var(--text-dark); font: inherit; font-size: var(--fs-2xs); font-weight: 600; }
.scroll-lab input[type="range"] { flex: 1 1 160px; accent-color: var(--accent-orange); }
.scroll-lab output { font-variant-numeric: tabular-nums lining-nums; font-weight: 800; min-width: 4.5em; text-align: right; }

.lab-sum { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.lab-sum > div { flex: 1 1 120px; background: var(--card-parchment); border: 1.5px solid var(--wood-border); border-radius: var(--rad-sm); padding: 8px 12px; }
.lab-sum span { display: block; font-size: var(--fs-3xs); color: var(--muted-brown); font-weight: 700; }
.lab-sum b { font-size: var(--fs-md); color: var(--accent-text); font-variant-numeric: tabular-nums lining-nums; }
.lab-sum b.bad { color: var(--red); }

/* 分佈用橫條，不用圖表庫 —— 20 行 CSS 做得到的事不值得多載 40KB */
.lab-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
.lab-bars li { display: grid; grid-template-columns: 4.5em 1fr 3.6em; align-items: center; gap: var(--sp-3); font-size: var(--fs-3xs); }
.lab-bars .lb-k { font-weight: 800; font-variant-numeric: tabular-nums lining-nums; }
.lab-bars .lb-bar { background: rgba(184, 154, 118, .18); border-radius: var(--rad-pill); height: 13px; overflow: hidden; }
.lab-bars .lb-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-gold-light, #ffcf8a), var(--accent-orange)); border-radius: var(--rad-pill); transition: width var(--dur-3) var(--ease-out); }
.lab-bars .lb-bar i.bad { background: linear-gradient(90deg, #f3b1a0, var(--red)); }
.lab-bars .lb-v { text-align: right; font-variant-numeric: tabular-nums lining-nums; color: var(--muted-brown); font-weight: 700; }
@media (prefers-reduced-motion: reduce) { .lab-bars .lb-bar i { transition: none; } }

/* 首頁「現在誰在掛機」：原本是純連結，現在每張卡多一顆「裝備」 */
.player { display: flex; align-items: stretch; gap: 0; }
.player .pl-main { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 0; text-decoration: none; color: inherit; padding: 8px 10px; }
.player .pl-gear {
  flex: 0 0 auto; align-self: stretch; border: none; border-left: 1.5px solid var(--wood-border);
  background: var(--card-parchment); color: var(--text-brown); font: inherit; font-size: var(--fs-3xs);
  font-weight: 800; padding: 0 12px; cursor: pointer; transition: background var(--dur-fast) var(--ease);
}
.player .pl-gear:hover { background: var(--accent-gold-light, #ffe9c4); }
.player .pl-gear:focus-visible { outline: 3px solid var(--accent-orange); outline-offset: -3px; }

/* ═══ 命中率計算（怪物頁）══════════════════════════════════════════════════ */
.hc-out { margin: var(--sp-3) 0; }
.hc-big { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; padding: 10px 14px; border-radius: var(--rad-md); border: 1.5px solid var(--wood-border); background: var(--card-parchment); }
.hc-big b { font-size: clamp(30px, 5vw, 44px); line-height: 1; font-variant-numeric: tabular-nums lining-nums; }
.hc-big span { font-size: var(--fs-2xs); color: var(--muted-brown); font-weight: 700; }
.hc-big.good b { color: #1e7d46; }
.hc-big.mid b { color: #c86a12; }
.hc-big.bad b { color: var(--red); }
.hc-facts { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 6px; }
.hc-facts li { display: flex; justify-content: space-between; gap: 8px; background: var(--card); border: 1px solid var(--line); border-radius: var(--rad-sm); padding: 6px 10px; font-size: var(--fs-3xs); }
.hc-facts b { font-variant-numeric: tabular-nums lining-nums; color: var(--text-title); }
.hc-facts b.good { color: #1e7d46; }
.hc-facts b.bad { color: var(--red); }
.hitcalc .lab-row { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.hitcalc label { font-weight: 800; font-size: var(--fs-2xs); color: var(--muted-brown); min-width: 5.5em; }
.hitcalc input[type="range"] { flex: 1 1 180px; accent-color: var(--accent-orange); }
.hitcalc output { font-variant-numeric: tabular-nums lining-nums; font-weight: 800; min-width: 3.5em; text-align: right; }

/* 製作：「做幾個要多少」 */
.cf-calc { margin-top: 10px; border-top: 1px dashed var(--wood-border); padding-top: 9px; }
.cf-calc > summary { cursor: pointer; font-size: var(--fs-3xs); font-weight: 800; color: var(--accent-text); list-style: none; }
.cf-calc > summary::-webkit-details-marker { display: none; }
.cf-calc > summary::before { content: "▸ "; }
.cf-calc[open] > summary::before { content: "▾ "; }
.cf-calc .lab-row { display: flex; align-items: center; gap: 10px; margin: 9px 0; }
.cf-calc label { font-size: var(--fs-3xs); font-weight: 800; color: var(--muted-brown); }
.cf-calc input[type="range"] { flex: 1; accent-color: var(--accent-orange); }
.cf-calc .cf-qty-out { font-size: var(--fs-3xs); font-weight: 800; min-width: 4em; text-align: right; font-variant-numeric: tabular-nums lining-nums; }
.cf-costlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
.cf-costlist li { display: flex; align-items: center; gap: 7px; font-size: var(--fs-3xs); }
.cf-costlist .cf-n { font-weight: 800; color: var(--accent-text); font-variant-numeric: tabular-nums lining-nums; }
.cf-costlist .cf-from { margin-left: auto; color: var(--muted-brown); text-align: right; }
.cf-total { margin: 9px 0 0; font-size: var(--fs-3xs); color: var(--muted-brown); }
.cf-total b { color: var(--text-title); font-variant-numeric: tabular-nums lining-nums; }

/* 職業頁：技能點預算 */
.spcalc .lab-row { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.spcalc label { font-weight: 800; font-size: var(--fs-2xs); color: var(--muted-brown); }
.spcalc input[type="range"] { flex: 1; accent-color: var(--accent-orange); }
.spcalc output { font-variant-numeric: tabular-nums lining-nums; font-weight: 800; min-width: 4em; text-align: right; }
.sp-big { display: flex; align-items: baseline; gap: 8px; }
.sp-big b { font-size: clamp(28px, 4.5vw, 40px); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums lining-nums; }
.sp-big span { font-size: var(--fs-2xs); color: var(--muted-brown); font-weight: 700; }
.sp-bar { position: relative; height: 15px; margin: 9px 0; background: rgba(184, 154, 118, .18); border-radius: var(--rad-pill); overflow: hidden; }
.sp-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-gold-light, #ffcf8a), var(--accent-orange)); transition: width var(--dur-3) var(--ease-out); }
.sp-bar span { position: absolute; inset: 0; display: grid; place-items: center; font-size: var(--fs-3xs); font-weight: 800; color: var(--text-brown); }
@media (prefers-reduced-motion: reduce) { .sp-bar i { transition: none; } }

/* 突襲：隊伍組成檢查 */
.pc-pick { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: var(--sp-3); }
.pc-job { display: inline-flex; align-items: center; gap: 6px; background: var(--card); border: 1.5px solid var(--wood-border); border-radius: var(--rad-pill); padding: 5px 13px; font-size: var(--fs-2xs); font-weight: 800; cursor: pointer; }
.pc-job:has(input:checked) { background: var(--tint-warm); border-color: var(--accent-orange); }
.pc-job input { accent-color: var(--accent-orange); }
.pc-n { font-size: var(--fs-2xs); font-weight: 800; color: var(--muted-brown); margin-left: auto; }
.pc-n input { width: 3.6em; padding: 4px 7px; border: 1.5px solid var(--wood-border); border-radius: var(--rad-sm); background: var(--card); color: var(--text-dark); font: inherit; font-weight: 800; text-align: center; }
.pc-boss { border: 1.5px solid var(--wood-border); border-radius: var(--rad-sm); padding: 9px 12px; margin-bottom: 7px; background: var(--card); }
.pc-boss.ok { border-left: 4px solid #2e7d32; }
.pc-boss.bad { border-left: 4px solid var(--red); }
.pc-boss h4 { margin: 0; font-size: var(--fs-2xs); display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.pc-boss h4 span { font-weight: 700; color: var(--muted-brown); }
.pc-boss.bad h4 span { color: var(--red); }
.pc-boss ul { margin: 6px 0 0; padding-left: 1.1em; font-size: var(--fs-3xs); }
.pc-boss p { margin: 6px 0 0; font-size: var(--fs-3xs); }

/* 地圖頁：掛機效率試算 */
.mc-pick { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: var(--sp-3); }
.mapcalc .lab-row { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.mapcalc label[for="mc-lv"] { font-weight: 800; font-size: var(--fs-2xs); color: var(--muted-brown); }
.mapcalc input[type="range"] { flex: 1; accent-color: var(--accent-orange); }
.mapcalc output { font-variant-numeric: tabular-nums lining-nums; font-weight: 800; min-width: 4em; text-align: right; }
.mc-out .lab-bars { margin-top: var(--sp-3); }
.mc-out .lb-k { width: 4.5em; }

/* ═══ 怪物列表：我這一級該打哪一隻 ═══════════════════════════════════════
   清單本來只能篩。這一區是整頁唯一「會回答你問題」的地方，所以放在篩選列
   之上、而且一進頁面就有答案（不用先按什麼）。 */
.mobfit .lab-row { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.mobfit label[for="mf-lv"], .mobfit label[for="mf-acc"] { font-weight: 800; font-size: var(--fs-2xs); color: var(--muted-brown); min-width: 5.5em; }
.mobfit input[type="range"] { flex: 1 1 180px; accent-color: var(--accent-orange); }
.mobfit output { font-variant-numeric: tabular-nums lining-nums; font-weight: 800; min-width: 3.5em; text-align: right; }
.mf-head { margin: 0 0 var(--sp-3); font-size: var(--fs-2xs); color: var(--text-brown); }
.mf-head b { color: var(--accent-text); font-variant-numeric: tabular-nums lining-nums; }
/* 第四欄（在哪張圖打）在窄螢幕換行到下一列，不跟數字擠成一團 */
.mf-rank li { grid-template-columns: minmax(8.5em, 14em) 1fr 4.6em; row-gap: 2px; padding: 3px 0; border-bottom: 1px dashed var(--line); }
.mf-rank .lb-k { width: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mf-rank .lb-k a { color: var(--text-title); text-decoration: none; }
.mf-rank .lb-k a:hover { text-decoration: underline; }
.mf-where { grid-column: 1 / -1; font-size: var(--fs-3xs); color: var(--muted-brown); font-weight: 700; }
.mf-where a { color: var(--muted-brown); }

/* ═══ 外觀頁：這一套要花多少 ═════════════════════════════════════════════
   鑽石是全服唯一只能打怪掉的貨幣，所以價錢旁邊一定要擺「換算成多少隻怪」。 */
.lc-list { list-style: none; margin: 0 0 var(--sp-3); padding: 0; display: grid; gap: 3px; }
.lc-list li { display: grid; grid-template-columns: 3.6em 1fr auto; align-items: center; gap: var(--sp-3); font-size: var(--fs-3xs); background: var(--card); border: 1px solid var(--line); border-radius: var(--rad-sm); padding: 5px 9px; }
.lc-list .lc-w { font-weight: 800; color: var(--muted-brown); }
.lc-list .lc-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lc-list b { font-variant-numeric: tabular-nums lining-nums; color: var(--accent-text); }
.lookcost .lab-row { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.lookcost label[for="lc-lv"] { font-weight: 800; font-size: var(--fs-2xs); color: var(--muted-brown); }
.lookcost input[type="range"] { flex: 1 1 160px; accent-color: var(--accent-orange); }
.lookcost output { font-variant-numeric: tabular-nums lining-nums; font-weight: 800; min-width: 4em; text-align: right; }
.lc-act { display: flex; justify-content: flex-end; }
.lc-act button { cursor: pointer; }
.lc-code-row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin: 0 0 var(--sp-3); padding: 6px 10px; background: var(--card); border: 1px solid var(--line); border-radius: var(--rad-sm); font-size: var(--fs-3xs); }
.lc-code-row .lc-w { font-weight: 800; color: var(--muted-brown); }
.lc-code-row code { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 800; color: var(--text-brown); user-select: all; }

/* 彈藥格：重點是「還剩幾發」，不是色階（彈藥沒有卷軸也沒有 Net 加成） */
.slot-ammo {
  display: inline-block; font-size: var(--fs-3xs); font-weight: 800;
  color: var(--text-brown); background: var(--card-parchment);
  border: 1px solid var(--wood-border); border-radius: var(--rad-pill);
  padding: 1px 8px; font-variant-numeric: tabular-nums lining-nums;
}

/* ═══ 配點規劃器（職業頁）══════════════════════════════════════════════════
   本季技能重置是鎖的 —— 這一區的存在理由就是「先試再點」。 */
.bp-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin: var(--sp-4) 0 var(--sp-3); flex-wrap: wrap; }
.bp-head h4 { margin: 0; font-size: var(--fs-sm); color: var(--text-title); }
.bp-act { display: flex; gap: 7px; }
.bp-act .btn { padding: 5px 13px; font-size: var(--fs-3xs); }

.bp-list { display: grid; gap: 3px; }
.bp-row {
  display: grid; grid-template-columns: 1fr 4.5em auto; align-items: center; gap: var(--sp-3);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--rad-sm);
  padding: 5px 10px; font-size: var(--fs-3xs);
}
.bp-row.on { border-color: var(--accent-ink); background: var(--card-parchment); }
.bp-row.off { opacity: .55; }
.bp-n { font-weight: 700; color: var(--text-title); }
.bp-lv { font-variant-numeric: tabular-nums lining-nums; font-weight: 800; text-align: right; }
.bp-btns { display: flex; gap: 4px; }
.bp-btns button {
  width: 26px; height: 26px; line-height: 1; border-radius: var(--rad-sm);
  border: 1.5px solid var(--wood-border); background: var(--card);
  color: var(--text-title); font: inherit; font-weight: 900; cursor: pointer;
}
.bp-btns button:hover:not(:disabled) { background: var(--accent-ink); color: var(--on-solid); border-color: var(--accent-ink); }
.bp-btns button:disabled { opacity: .35; cursor: not-allowed; }
.bp-btns button:focus-visible { outline: 3px solid var(--accent-orange); outline-offset: 2px; }
/* 前置沒滿的原因：佔整列，不要擠在旁邊被截斷 */
.bp-why { grid-column: 1 / -1; color: var(--red); font-size: var(--fs-3xs); }

/* ═══ 突襲頁補完（2026-10-05）═══════════════════════════════════════════════ */

/* 深連結 #/raids/<key> 捲過去之後，短暫標一下 —— 不標的話使用者不知道捲到哪了 */
.rk-focus { animation: rk-flash 2.4s var(--ease-out) 1; }
@keyframes rk-flash {
  0%, 60% { box-shadow: 0 0 0 3px var(--accent-ink), var(--e2); }
  100% { box-shadow: 0 0 0 0 transparent, var(--e2); }
}
@media (prefers-reduced-motion: reduce) {
  .rk-focus { animation: none; box-shadow: 0 0 0 3px var(--accent-ink), var(--e2); }
}

/* 專屬裝備沒有官方圖（本服自創的純數值裝備）→ 標部位的佔位，不要借別人的圖騙人 */
.rk-exi .rk-exph,
.rk-exi.noimg::after {
  display: grid; place-items: center; width: 100%; height: 100%; min-height: 46px;
  border: 1.5px dashed var(--wood-border); border-radius: var(--rad-sm);
  background: var(--card-parchment); color: var(--muted-brown);
  font-size: var(--fs-3xs); font-weight: 800; text-align: center;
}
.rk-exi.noimg::after { content: "無圖"; }

/* ═══ 🌸 外觀 · 限定區塊（聯名造型）══════════════════════════════════════
   為什麼獨立一塊而不是塞進「時裝」分頁：一套聯名造型是「髮型＋套服＋鞋子」，
   而髮型跟時裝在這一頁本來就分屬兩個分頁 —— 混進去等於把一套衣服拆到兩個
   抽屜，而且 6 件會淹在 206 件基本款裡。限定就是要一眼看到。          */
#app:has(#lookbody) .collab {
  position: relative; overflow: hidden;
  margin: 0 0 20px; padding: 18px 18px 14px;
  border: 1.5px solid var(--line-strong); border-radius: var(--rad-lg);
  background:
    radial-gradient(70% 55% at 50% 0%, rgba(242, 101, 34, .10) 0%, transparent 72%),
    linear-gradient(180deg, var(--bg-paper) 0%, var(--card-parchment) 100%);
  box-shadow: var(--e2), var(--rim);
}
#app:has(#lookbody) .cb-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px; margin: 0 0 14px; }
#app:has(#lookbody) .cb-head h2 { margin: 0; font-size: var(--fs-lg); color: var(--text-title); }
#app:has(#lookbody) .cb-sub { margin: 0; flex: 1 1 100%; color: var(--muted); font-size: var(--fs-xs); }
#app:has(#lookbody) .cb-tag {
  padding: 3px 11px; border-radius: var(--rad-pill);
  background: linear-gradient(180deg, var(--accent-ink) 0%, var(--accent-ink-deep) 100%);
  color: var(--on-solid); font-weight: 900; font-size: var(--fs-3xs); letter-spacing: .08em;
}
#app:has(#lookbody) .cb-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }
#app:has(#lookbody) .cb-ch {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 13px; border: 1px solid var(--line); border-radius: var(--rad-md);
  background: var(--card);
  transition: box-shadow var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
#app:has(#lookbody) .cb-ch.on { border-color: var(--accent-orange); box-shadow: 0 0 0 2px rgba(242, 101, 34, .22), var(--e1); }
#app:has(#lookbody) .cb-shot { flex: 0 0 auto; }
#app:has(#lookbody) .cb-shot img {
  display: block; width: 94px; height: 120px; object-fit: contain;
  image-rendering: pixelated;
  filter: drop-shadow(0 3px 5px rgba(90, 60, 25, .26));
}
#app:has(#lookbody) .cb-info { flex: 1 1 auto; min-width: 0; }
#app:has(#lookbody) .cb-info h3 { margin: 0 0 2px; font-size: var(--fs-md); color: var(--text-title); }
#app:has(#lookbody) .cb-price { margin: 0 0 9px; font-size: var(--fs-xs); color: var(--muted); }
#app:has(#lookbody) .cb-price b { color: var(--accent-ink); font-size: var(--fs-sm); }
/* 用 grid 不用 flex：格子寬度要由**剩下多少空間**決定，不是由名字長度。
   flex 版本會讓「愛蜜莉雅的套服」把格子撐寬，三格排不下掉到第二行，
   隔壁「雷姆」卻排得下 —— 四張卡片高矮不一。 */
#app:has(#lookbody) .cb-items {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
  gap: 8px; margin: 0 0 11px;
}
/* 髮型格跟部件格排在同一列，所以高度要對齊 —— 頭像是方的，立繪是長的 */
#app:has(#lookbody) .cb-items .lookcell.head { padding: 8px 7px 7px; align-self: stretch; display: flex; flex-direction: column; justify-content: center; }
#app:has(#lookbody) .cb-items .lookcell.head img { width: 52px; height: 52px; margin: 0 auto; }
#app:has(#lookbody) .cb-items .lookcell.body { padding: 8px 7px 7px; }
#app:has(#lookbody) .cb-items .lookcell.body img { width: 52px; height: 68px; }
#app:has(#lookbody) .cb-items .lookcell figcaption { font-size: var(--fs-3xs); }
#app:has(#lookbody) .cb-all { cursor: pointer; font-family: inherit; }
#app:has(#lookbody) .cb-all.on {
  background: linear-gradient(180deg, var(--accent-ink) 0%, var(--accent-ink-deep) 100%);
  color: var(--on-solid); border-color: var(--accent-ink-deep);
}
#app:has(#lookbody) .cb-foot { margin: 12px 0 0; color: var(--muted); font-size: var(--fs-3xs); line-height: 1.7; }

/* 中等螢幕：卡片排兩欄的話，扣掉立繪之後剩不到三格的寬度，
   三件的角色就會掉到第二行、跟只有一件的角色高矮不一。改排一欄。 */
@media (max-width: 1100px) {
  #app:has(#lookbody) .cb-grid { grid-template-columns: 1fr; }
}
/* 窄螢幕：立繪與資訊上下疊，不要擠成兩條 */
@media (max-width: 520px) {
  #app:has(#lookbody) .collab { padding: 15px 14px 12px; }
  #app:has(#lookbody) .cb-ch { flex-direction: column; align-items: center; text-align: center; }
  /* ⚠️ 直排之後 .cb-info 會縮到內容寬 —— 不給 100% 的話裡面的 grid 只排得下一格，
     三件的角色就變成三行。 */
  #app:has(#lookbody) .cb-info { width: 100%; }
  #app:has(#lookbody) .cb-items { justify-content: center; }
}

/* ═══ 外觀 · 兩層選單 ════════════════════════════════════════════════════
   第一層是「這是哪一類」（美容／時裝），第二層才是細項。平鋪成一排的話，
   髮色與隱形眼鏡會跟時裝的十個部位擠在一起，看不出誰跟誰同一類。      */
#app:has(#lookbody) .lookmenu { margin: 0 0 14px; }
#app:has(#lookbody) .lm-1 { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 10px; }
#app:has(#lookbody) .lm-g {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  padding: 10px 18px; cursor: pointer; font-family: inherit; text-align: left;
  border: 1.5px solid var(--line-strong); border-radius: var(--rad-md);
  background: linear-gradient(180deg, var(--bg-paper) 0%, var(--card-parchment) 100%);
  color: var(--text-title);
  transition: box-shadow var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}
#app:has(#lookbody) .lm-g b { color: inherit; font-size: var(--fs-sm); font-weight: 900; }
#app:has(#lookbody) .lm-g small { font-size: var(--fs-3xs); color: var(--muted); font-weight: 600; }
#app:has(#lookbody) .lm-g:hover { box-shadow: var(--e1); transform: translateY(-1px); }
#app:has(#lookbody) .lm-g.on {
  border-color: var(--accent-ink-deep);
  background: linear-gradient(180deg, var(--accent-ink) 0%, var(--accent-ink-deep) 100%);
  color: var(--on-solid); box-shadow: var(--e2);
}
/* ⚠️ 選中時底色是實心深橘 —— 副標要跟著翻成白，用會翻轉的 --muted 會讀不到 */
#app:has(#lookbody) .lm-g.on small { color: var(--on-solid); }
#app:has(#lookbody) .lm-g[data-grp="collab"]:not(.on) { border-color: var(--accent-orange); }
#app:has(#lookbody) .lm-g[data-grp="collab"] b::before { content: "🌸 "; }
#app:has(#lookbody) .lm-2 { display: flex; flex-wrap: wrap; gap: 7px; }
#app:has(#lookbody) .lm-2:empty { display: none; }
/* 髮型／臉型格子的第二行小字（幾色、幾色瞳） */
#app:has(#lookbody) .lookcell .sub2 { display: block; margin-top: 2px; font-size: var(--fs-3xs); color: var(--muted); }
@media (max-width: 520px) {
  #app:has(#lookbody) .lm-1 { gap: 8px; }
  #app:has(#lookbody) .lm-g { flex: 1 1 calc(50% - 4px); padding: 9px 12px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   官方素材（2026-10-12）：轉蛋機台動圖 / 商店駐點商人立繪 / 裝備頁官方視窗框
   素材路徑全部由資料檔帶（site/data/gacha-art.json、shop-npc-art.json），
   這裡只管「有圖的時候怎麼擺」；沒圖的情況 app.js 根本不會印出那個元素。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 轉蛋頁：村莊 chip 帶一台小機台、選中的那台放大站在表格上方 ── */
.gm-chip { display: inline-flex; align-items: center; gap: 6px; }
.gm-chip img { width: 22px; height: 22px; object-fit: contain; object-position: bottom; image-rendering: pixelated; flex: 0 0 auto; }
.gm-stage {
  display: flex; align-items: center; gap: 16px; margin: 12px 0 10px; padding: 12px 16px;
  border: 1.5px solid var(--line-strong); border-radius: var(--rad-md);
  background: linear-gradient(180deg, var(--bg-paper) 0%, var(--card-parchment) 100%);
}
/* 官方動圖是 GIF，放大用像素風格才不會糊；底下留一道影子讓它「站」在紙上 */
.gm-stage img {
  width: 104px; height: 104px; flex: 0 0 auto; object-fit: contain; object-position: bottom;
  image-rendering: pixelated; filter: drop-shadow(0 6px 4px rgba(60, 35, 10, .18));
}
.gm-stage b { display: block; font-size: var(--fs-md); color: var(--text-title); margin-bottom: 2px; }
.gm-stage .muted { font-size: var(--fs-2xs); }
.gm-ic { display: inline-block; width: 28px; height: 28px; margin-right: 6px; vertical-align: middle; }
.gm-ic img { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }

/* ── 村莊商店：標題旁站一位官方立繪的商人 ── */
.shop-head-l { display: flex; align-items: center; gap: 14px; min-width: 0; }
.shop-npc { height: 72px; width: auto; max-width: 120px; flex: 0 0 auto; object-fit: contain; object-position: bottom; image-rendering: pixelated; }

/* ── 裝備頁：素質卡用官方「道具欄」視窗框（tools/wz/build-ui-frame.mjs 切的九宮格）──
   上緣 24px 是官方標題列（白底）：卡片標題擺進那一條帶；本體深底白字，像遊戲裡的道具說明框。
   ⚠️ 底色是寫死的深藍，字一律 --on-solid / 固定淺色，不可用會跟深色模式翻轉的代幣。
   ⚠️ background-clip 要是 padding-box：框的四角是透明的，底色漏到框外就會露出方角。 */
.gcard {
  position: relative; margin-top: 14px; padding: 10px 12px 12px;
  border: 8px solid transparent; border-top-width: 24px;
  border-image: url(ui/tooltip/frame.png) 24 8 8 8 / 24px 8px 8px 8px stretch;
  background: #141c2b; background-clip: padding-box; color: var(--on-solid);
  image-rendering: pixelated;
}
.gcard-t {
  position: absolute; left: 2px; right: 2px; top: -22px; height: 18px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font: 800 13px/18px "Noto Sans TC", Nunito, sans-serif; color: #1a202c; image-rendering: auto;
}
.gcard .kv { image-rendering: auto; }
.gcard .kv dt { color: #b9c6dd; }
.gcard .kv dd { color: var(--on-solid); }
.gcard .kv dd b { color: var(--on-solid); }
.gi { display: inline-block; width: 26px; height: 26px; margin-right: 6px; vertical-align: middle; }
.gi img { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }
@media (max-width: 520px) {
  .gm-stage { gap: 12px; padding: 10px 12px; }
  .gm-stage img { width: 84px; height: 84px; }
  .shop-npc { height: 56px; max-width: 90px; }
}
