/* ── muzix Admin · Piano App (PA) 分區樣式 ───────────────────────────────────────────────────
   PA-01.

   規矩：styles.css 嘅 class 一律**照用唔好抄**（.button / .chip / .queue-* / .badge / .view-head /
   .mini-empty / .loading / .toast / .modal-* …）—— 佢哋純樣式冇行為，本身就係 design token 層，
   係兩區外觀保持一致嘅唯一機制。呢個檔淨係放 styles.css 冇提供、而且真係 PA 專屬嘅嘢。

   ⚠️ 唔准喺呢度重新定義任何 styles.css 已有嘅 selector —— 咁樣等同郁 muzix 嘅外觀。
   ⚠️ 所有新 selector 一律收窄喺 PA 範圍內（#pa-workspace / .pa-*），唔准洩漏去 muzix 側。 */

/* Piano 區工作區。沿用 .workspace 嘅 padding / overflow / outline，呢度唔再定義。
   同 #workspace 係 .app-shell grid 入面嘅兄弟：任何時候只有一個唔 hidden，
   所以 grid 永遠都係 2 欄（[hidden]{display:none!important} 令另一個唔佔位）。 */

/* ── PA 區換色 —— 唯一一處覆蓋 design token ────────────────────────────────────────────────
   兩個區共用一個 login，視覺分唔開，同事就會喺 PA 區揾 muzix 功能（或者反過嚟）。呢個係
   防呆，唔係美化。

   🔒 做法：**scoped override，唔係新一套 style system**。styles.css 嘅 `:root` 一個 byte 都冇郁，
      所以 muzix 區色零改動；class `pa-mode` 由 pa-app.js 喺 paEnter()／paExit() 加減（耦合點 #12）。
      styles.css 所有 accent 都行 var(--admin-*)，所以覆蓋五條就夠 —— 唔使 hardcode 任何色值。
   ⚠️ 唯一覆蓋唔到嘅三處：styles.css 入面 .edition-card / .task-card / .skill-card 嘅
      `rgba(232,109,133,.08)` 硬編陰影。三個都係 muzix 專用 component，PA 一個都冇用，所以冇影響。
   ⚠️ 唔准撞 --success / --warning / --danger —— 撞咗狀態色就冇咗語義。
   🔴 **湖水藍同 --success 綠係鄰居**（--success:#237458 H159° vs accent:#1f7a80 H183°，
      兩條嘅明度差唔多一樣：L30% vs L31%）。分辨靠**色相 24° 嘅差**，唔係深淺。
      兩者都以填色／文字形式出現喺同一個畫面（.badge-success 就住喺右欄同 worklist），
      所以改呢五條色嘅時候一定要重驗呢一對，唔好淨係睇 accent 自己靚唔靚。
   🔴 `--admin-panel` 由 #e3f1f2 改咗做 #e2eff5（推向藍離開綠）：原本嗰個同 `--success-bg`
      #e8f4ee 得 ΔE 3.4（<5 = 一般人分唔到），而 `.pa-tree-row.is-selected` 就係用 panel 做底、
      `.badge-success` 就住喺嗰行 —— 揀中一行，個 success badge 個底會消失，冇報錯冇訊號。
      #e2eff5 拉到 5.9，deep 字對比仍然 6.64:1。 */

/* ① PA 自己嘅色盤。放喺 `#app` 而**唔係** `:root` —— 亦都唔係淨係放喺 `.pa-mode`：
   muzix 區（冇 `pa-mode`）都要讀得到，因為轉區掣要用「目的地」色，喺 muzix 區嗰陣係湖水藍。
   五個值全世界只寫一次。 */
#app {
  --pa-accent: #1f7a80;
  --pa-deep: #155b60;
  --pa-panel: #e2eff5;
  --pa-surface: #f8fcfc;
  --pa-line: #c2dfe1;
}

/* ② 反方向：捕捉 muzix 原色，畀 PA 區嗰個 [⇄ muzix] 掣用。
   🔴 **一定要喺 `body`（或者任何 `#app` 嘅祖先）做，唔可以喺 `#app` 做。**
      `var()` 喺邊個元素宣告就喺嗰個元素解析，而 `#app` 上面 `--admin-accent` 已經畀下面
      ③ 覆蓋成湖水藍 —— 喺嗰度捕捉會攞到湖水藍，靜靜錯。`body` 讀到嘅永遠係 `:root` 嗰個
      粉紅，因為後代嘅 override 改唔到祖先。
   咁樣就零硬編：muzix 粉紅嘅真相源仍然係 styles.css 個 `:root`，佢日後改色呢邊自動跟。
   ⚠️ 呢兩條係 inert custom property —— muzix 冇任何 selector 讀 `--pa-*`，對 muzix 零視覺
      影響。連同 ① 一齊登記喺 pa-schema.js 耦合點 #12。 */
body {
  --pa-muzix-accent: var(--admin-accent);
  --pa-muzix-deep: var(--admin-deep);
}

/* ③ 入咗 PA 區先 map 落 muzix 個 token 名。 */
#app.pa-mode {
  --admin-accent: var(--pa-accent);
  --admin-deep: var(--pa-deep);
  --admin-panel: var(--pa-panel);
  --admin-surface: var(--pa-surface);
  --admin-line: var(--pa-line);
}

/* ── 轉區掣 = 目的地色，唔係狀態色 ──────────────────────────────────────────────────────────
   個掣係一個**預告**：撳之前就知道會去到一個唔同色嘅系統。所以 muzix 區嗰個著湖水藍（PA 色）、
   PA 區嗰個著粉紅（muzix 色）—— 同「我而家喺邊」啱啱相反。
   `#pa-switch` 係 PA 自己嘅元素（PA-01 加落 muzix topbar 嗰個），所以由 pa.css 管佢係本分，
   同 `.pa-*` 一樣喺 PA 命名空間內。
   白字由 styles.css 嘅 `.button-primary` 提供（pa-app.js 由頭到尾掛住嗰個 class），呢度唔碰
   `color`，亦冇硬編任何色值。
   🔴 PA 區用 `--pa-muzix-deep`(#c9526b) 而唔係 `--pa-muzix-accent`(#e86d85) 做底：白字喺
      #e86d85 上面得 3.02:1，12px 字太蠟，而且淺粉紅喺湖水藍環境入面唔夠力；#c9526b 有
      4.28:1，兩者 ΔE 9.4 = 一望仍然知係粉紅系。hover 先跳去 accent。 */
#pa-switch { background: var(--pa-accent); border-color: transparent; }
#pa-switch:hover { background: var(--pa-deep); }
#app.pa-mode #pa-switch { background: var(--pa-muzix-deep); }
#app.pa-mode #pa-switch:hover { background: var(--pa-muzix-accent); }

/* ── PA 區佈局：左 nav + 右內容 ────────────────────────────────────────────────────────────
   PA 自己條 rail 畫喺 #pa-workspace **入面**，唔係插入 muzix 個 #rail（理由見 pa-app.js
   paEnter() 上面 #13）。所以要喺呢度攤平 .workspace 嘅 padding，交返畀 .pa-main。
   `:not([hidden])` 唔係為咗贏 specificity（styles.css 個 [hidden] 有 !important），係為咗
   將來就算有人拎走個 !important，呢條規則都唔會令收埋咗嘅區重新顯示。
   用 flex 唔用 grid：冇 rail 嗰個 case（role 一頁都入唔到）唔會留低一條空欄。 */
/* 🔴 收起 #rail 之後**一定**要收埋 .app-shell 嗰條 215px 欄。
   styles.css:84 係 `grid-template-columns:215px minmax(0,1fr)`，而 grid 只計「有喺 flow 入面」
   嘅子元素：#rail 一 hidden（display:none）就唔再佔位，剩返嘅 #pa-workspace 會自動排入
   **第一欄**，即係成個 PA 區被壓成 215px 闊。呢個喺 ≥1440px 兼且 rail-open（預設）先出現，
   窄螢幕反而冇事（嗰度本身已經係單欄），所以最容易喺大螢幕上面先撞到。
   選擇器 1-2-0，贏得過 styles.css:84（0-1-0）同 :91（1-1-0）。 */
#app.pa-mode .app-shell { grid-template-columns: minmax(0, 1fr); }
/* 🔴 同一組陷阱嘅另一半：<1440px 嗰陣 `#app.rail-open .rail-backdrop{display:block}`。
   如果用家喺窄螢幕開咗個 drawer 先入 PA 區，`rail-open` 仲喺 #app 上面，個 backdrop 就會
   蓋住成個 PA 區（z-index 55）—— 而 ☰ 已經收埋，佢撳唔返走，即係成頁死鎖。
   用 id 選擇器（2-1-0）而唔係 `.rail-backdrop`，咁就唔使靠 pa.css 排喺 styles.css 後面。 */
#app.pa-mode #rail-backdrop { display: none; }
#pa-workspace:not([hidden]) { display: flex; align-items: stretch; padding: 0; }
.pa-rail { flex: none; width: 215px; border-right: 1px solid var(--line); background: var(--paper); padding: 20px 12px; }
.pa-main { flex: 1; min-width: 0; padding: 24px; }
/* .nav-item 嘅副標題。刻意唔用 <small>（同 .pa-key 一樣嘅理由：<small> 數目係 index.html
   L1/L2 baseline 之一，PA 唔應該畀任何「數全頁 small」嘅檢查加數）。 */
.pa-nav-sub { color: var(--ink-3); font: 10px var(--mono); }
.pa-rail .nav-item:disabled { opacity: .45; cursor: not-allowed; }
/* 窄螢幕跟返 styles.css:557 嘅 .workspace padding，兩區留白先一致。
   ⚠️ PA 條 rail 唔會變 overlay drawer —— 佢住喺 #pa-workspace 入面，三項永遠睇得到。 */
@media (max-width: 1439px) {
  .pa-main { padding: 18px; }
  .pa-rail { width: 180px; }
  .pa-cat-split { grid-template-columns: minmax(200px, 280px) minmax(0, 1fr); gap: 14px; }
}

/* type A worklist 嘅欄寬。.queue / .queue-head / .queue-row 由 styles.css 提供，
   每個 queue 變體只需要自己嘅 grid-template-columns（同 .queue-verify 一樣嘅做法 ——
   .queue-production 喺 2026-08-12 隨個 queue 一齊拆走咗）。五欄：Score Code | Song |
   Task | 狀態 | 動作。
   「待上載」同「已上載」兩組共用同一組欄寬，兩張表先會對得齊。 */
.pa-worklist .queue-head,
.pa-worklist .queue-row {
  grid-template-columns: minmax(92px, auto) minmax(84px, .9fr) minmax(120px, 1.5fr) minmax(120px, auto) minmax(96px, auto);
}

/* Page 2 — Audience Groups。五欄：Value | Display name | Tier | Sort | Actions。 */
.pa-groups .queue-head,
.pa-groups .queue-row {
  grid-template-columns: minmax(84px, auto) minmax(140px, 1.6fr) minmax(120px, auto) minmax(48px, auto) minmax(120px, auto);
}
/* 表入面有、但唔喺 PA_TIER_CHAIN 內嘅殘留 row。刻意仲睇得見 —— 隱藏個 drift 就變成靜靜爛。 */
.pa-groups .queue-row.is-inactive { background: var(--soft); }
.pa-groups .queue-row.is-inactive strong { color: var(--ink-2); }

/* ── Page 3 — Categories：左樹 + 右列表 ────────────────────────────────────────────────────
   🔴 樹**冇固定層數**。縮排由**逐層一格 `.pa-guide`** 撐出嚟（格數由 walk 出，見下面連接線
      個 block）—— 呢度冇任何 .depth-1 / .depth-2 / .depth-3 class，亦冇「level × 固定 px」，
      兩樣都唔准加。葉 = 冇 child，唔係 depth === 3。 */
.pa-cat-split { display: grid; grid-template-columns: minmax(240px, 340px) minmax(0, 1fr); gap: 20px; align-items: start; }
.pa-tree { display: grid; gap: 1px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); padding: 8px; }
.pa-tree-row { display: flex; align-items: center; gap: 4px; border-radius: 9px; }
.pa-tree-row.is-selected { background: var(--admin-panel); }
/* 展開掣同「冇 child」嘅留白同闊 —— 唔對齊嘅話同一層嘅名會歪開。 */
.pa-twisty {
  display: grid; place-items: center; width: 22px; height: 26px; flex: none;
  border: 0; border-radius: 7px; background: transparent; color: var(--ink-3);
  font-size: 11px; line-height: 1; cursor: pointer;
}
.pa-twisty:hover { background: var(--soft); color: var(--ink); }
.pa-twisty-none { cursor: default; }
.pa-tree-name {
  display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0;
  border: 0; background: transparent; padding: 6px 6px; text-align: left; cursor: pointer;
}
.pa-tree-name:hover .pa-tree-title { color: var(--admin-deep); }
.pa-tree-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 600; color: var(--ink); }

/* 右欄。標題行、child chip 行、同直接掛喺呢個節點嘅 task（兩欄：Task | State）。 */
.pa-detail { display: grid; gap: 14px; align-content: start; min-width: 0; }
.pa-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.pa-detail-title { min-width: 0; }
.pa-detail-title h2 { margin: 2px 0 4px; font-size: 18px; }
.pa-child-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.pa-cat-tasks .queue-head,
.pa-cat-tasks .queue-row {
  grid-template-columns: minmax(180px, 1fr) minmax(150px, auto);
}

/* ── 詳情區上半框（S-2a）────────────────────────────────────────────────────────────────────
   節點屬性由「一句用 · 串埋嘅字」改成一個**有托底嘅格陣**。點解要框：上半（呢個節點係咩）
   同下半（呢個節點入面有咩）係兩件事，之前兩者之間冇任何邊界，讀落似同一段。
   📌 格陣本身就係 S-3 嘅留位機制 —— 加一格係加一個 div，唔使拆骨架。 */
/* 卡圖喺左、其餘喺右。卡圖係唯一一樣有固定形狀嘅嘢（一個方框），所以佢做錨；
   右邊嗰堆係逐格文字，闊度隨內容行。 */
.pa-detail-box {
  /* 左欄 `auto` = 貼住卡圖嗰個固定闊度收（S-2c）。之前係一個 120–168px 嘅範圍，
     而張卡而家自己有闊度 —— 兩個地方各講一次闊度，就會喺卡右邊留一條死位。 */
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 14px 18px; align-items: start;
  border: 1px solid var(--line); border-radius: 12px; background: var(--soft); padding: 14px 16px;
}
.pa-detail-crumb { margin: 0 0 8px; }
.pa-detail-card-col { display: grid; gap: 4px; }
.pa-detail-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px 18px; align-content: start; }
/* 🔴 三粒掣係**節點層**動作（改呢個節點、換佢張卡圖、刪佢），唔屬於框內任何一格資料。
   補版① 佢哋擺喺 `.pa-detail-facts` 入面，跌落最後一格下面 —— 讀落似係嗰格嘅掣。
   ⟹ 提升做 `.pa-detail-box` 嘅直接仔，佔成行、跨埋卡圖欄，加一條分隔線。
   ⚠️ 揀「框底成行」而唔揀「框右上角」：右上角要靠絕對定位先離得開個格陣，DOM 上面
      佢仍然坐喺某一個容器入面，而「唔屬於任何一格」呢件事就變成純視覺、驗唔到。
      提升出嚟係**結構**講嘅 —— `.pa-detail-facts` 入面根本冇咗佢哋，一條反向斷言就釘死。 */
.pa-detail-actions {
  grid-column: 1 / -1; justify-content: flex-start;
  border-top: 1px solid var(--line); margin-top: 2px; padding-top: 12px;
}
@media (max-width: 719px) { .pa-detail-box { grid-template-columns: minmax(0, 1fr); } }
.pa-detail-field { display: grid; gap: 3px; min-width: 0; }
/* 受眾嘅斷行政策唔喺呢度 —— 佢得一個定義點，喺下面受眾本身嗰條規則。 */
.pa-detail-label { color: var(--ink-3); font-size: 10px; font-weight: 700; letter-spacing: .04em; }
/* ⛔ 留位唔准扮空 —— 一格空白會被讀成「未做完」或者「壞咗」，而佢實際上係
   「呢一輪明文唔做」。淡啲、但睇得見。 */
.pa-detail-field.is-pending { opacity: .6; }
/* 簡介佔全行 —— 其餘每格都係一兩個字，佢係一句話。同右欄嗰個 auto-fit 格陣夾住一格
   就會擠成一條窄柱。⚠️ 觀感（行高、要唔要限行數）係視覺層，靠人喺 preview 睇。 */
.pa-detail-blurb { grid-column: 1 / -1; }
/* 卡圖位。S-2b 起入面係真圖 —— 經自己個代理 route 攞，桶嘅 Public Access 維持關閉。
   🔴 S-2c：**直向 3:4**。個闊度刻意細（116px ⟹ 高度約 155px）——
      上半框唔應該變主角，下面張 song list 要仍然喺同一屏入面睇得到。
      ⚠️ 600×800 係**上載建議尺寸**，唔係呢個顯示框嘅尺寸；兩樣同比例，唔同用途。
   `aspect-ratio` 令兩個狀態（有圖／冇圖）同一個形，所以由冇圖變有圖唔會跳版。
   個闊度寫落卡圖本身而唔係寫落格陣個欄：窄畫面嗰陣格陣會塌成一欄，欄闊變成成行闊，
   如果尺寸靠欄嚟定，張卡就會喺手機度變成一張成頁咁高嘅直板。 */
.pa-detail-card {
  position: relative; display: grid; place-items: center;
  width: 116px; max-width: 100%; aspect-ratio: 3 / 4;
  border: 1px dashed var(--line); border-radius: 9px; background: var(--paper); padding: 6px;
}
.pa-detail-card.is-stored { border-style: solid; padding: 0; overflow: hidden; }
/* cover：填滿個框、⛔ 唔留白邊，多出嗰邊裁走。 */
.pa-detail-card-img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* 建議尺寸。⛔ 唔係警告 —— 用返 note 嘅淡色，同「未有卡圖」同一級，唔搶眼。 */
.pa-card-hint { font-size: 9px; line-height: 1.35; text-align: center; }
/* hover 兩粒掣。⚠️ 用 opacity 而唔用 `display: none` / `visibility: hidden`：後兩者會令粒掣
   對焦唔到，於是 `:focus-within` 永遠唔會 fire，鍵盤用家就完全去唔到嗰粒掣。opacity 0
   嘅嘢仍然對焦得到，所以 Tab 過去就會現形。
   ⛔ 亦冇加 `pointer-events: none` —— 加咗就要靠 hover 先撳得到，而 hover 喺觸控上唔存在。
      個卡圖位本身冇 click 動作，所以一粒睇唔見但撳得到嘅掣喺呢度唔會搶走任何嘢。 */
.pa-card-hover {
  position: absolute; inset: auto 0 0 0; display: flex; justify-content: center; padding: 6px;
  background: linear-gradient(to top, rgba(0, 0, 0, .55), transparent);
  opacity: 0; transition: opacity .12s ease;
}
.pa-detail-card:hover .pa-card-hover, .pa-card-hover:focus-within { opacity: 1; }

/* 狀態欄：可能同時有 file status ＋ placement ＋ 受眾三個 badge，所以要 wrap。 */
.pa-sync { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
.pa-actions { display: flex; gap: 6px; justify-content: flex-end; }

/* 已上載嗰行嘅 R2 key。刻意唔用 <small>：index.html 個 shell 嘅 small 數係 L1/L2 baseline
   之一，任何「數全頁 small」嘅檢查都會連 PA 區一齊數落去。 */
.pa-key {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-3);
  font-size: 10px;
}

/* 上載表單。.modal-card 提供外框同間距，呢度只加闊少少（多咗 file / select / radio 三行）
   同 placement 嗰行嘅排版。 */
.pa-upload-card { max-width: 480px; }
/* 未上載嘅音軌位。刻意留住個位而唔係唔顯示 —— 三個位睇得晒先知差邊條。 */
.pa-track-missing { opacity: .5; }
/* 🔴 兩條 `min-width: 0` 唔係裝飾 —— 冇咗佢哋，Tracks 窗會由右邊爆出卡片。
   鏈係咁：`.pa-key` 係 `white-space: nowrap`，佢個 min-content 就係成條 R2 key 嘅長度。
   下面 `> div:first-child` 嗰個 `min-width: 0` 只解決到「flex item 縮唔細」嗰一層；
   但 `.pa-track-line` 係 `.pa-track-list` 嘅 grid item，`.pa-track-list` 又係 `.modal-card`
   嘅 grid item，兩層 grid item 嘅 min-width 都係 `auto` ⟹ 條 key 嘅 min-content 一路傳上去，
   將卡片個 auto track 由 434px（內容區）撐到 480px，於是**每一個** grid item 都變 480 闊，
   Remove 掣同底下嗰句說明文字一齊出界。
   ⚠️ `overflow: hidden` ＋ ellipsis 攔唔到呢件事 —— 佢哋管「畫出嚟點截」，
      唔管「intrinsic sizing 嗌幾闊」。量過：加咗之後 .pa-manage-card 側嘅幾何**逐項不變**
      （min-width: 0 只係攞走一個下限，唔會令任何嘢變闊）。 */
.pa-track-list { display: grid; min-width: 0; gap: 10px; }
.pa-track-line { display: flex; align-items: center; justify-content: space-between; min-width: 0; gap: 12px; border: 1px solid var(--line); border-radius: 11px; padding: 10px 12px; }
.pa-track-line > div:first-child { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.pa-track-line-actions { display: flex; gap: 6px; flex: none; }
.pa-note { color: var(--ink-3); font-size: 11px; }
/* 上載成功但有軟提示嗰個面板。用 ul 而唔用一堆 .modal-warning：呢啲唔係錯誤，唔應該全部紅。 */
.pa-note-list { margin: 0; padding-left: 18px; color: var(--ink-2); font-size: 12px; line-height: 1.6; }
.pa-note-list li + li { margin-top: 4px; }
.pa-radio-row { display: flex; gap: 14px; align-items: center; }
.pa-radio { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 13px; }
.pa-radio input { width: 15px; height: 15px; accent-color: var(--admin-accent); }

/* 分類多選。冇數量上限，所以要捲；一首歌可以同時掛幾個葉。 */
.pa-leaf-list { display: grid; gap: 2px; max-height: 190px; overflow-y: auto; border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.pa-leaf { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 12px; line-height: 1.5; }
.pa-leaf input { width: 14px; height: 14px; flex: none; accent-color: var(--admin-accent); }
.pa-leaf span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Score Production 交接（2026-08-12）──────────────────────────────────────────────────────
   四組共用 .pa-worklist 嗰組欄寬（上面已經定義），所以四張表對得齊。呢度只加交接帶嚟嘅
   三樣新嘢：發還重做嗰行嘅標示、Jenny 寫低嘅原因、已驗收組嘅搜尋框。 */
/* 發還重做：一行要一眼認得出，但唔用紅色 —— 佢係「要再做」唔係「出錯」。 */
.pa-worklist .queue-row.is-rework { background: var(--warning-bg); }
.pa-return-reason { display: block; margin-top: 3px; color: var(--warning); font-size: 11px; line-height: 1.5; }
.pa-return-reason b { font-weight: 700; }
/* 已驗收組嘅搜尋。呢組冇上限（冇 verified 時間欄，做唔到「最近 N 條」），所以搜尋唔係
   裝飾 —— 佢係搵返一條舊 task 嘅唯一方法。 */
.pa-search { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; }
.pa-search span { flex: none; color: var(--ink-3); font-size: 11px; }
.pa-search input { max-width: 320px; }
.queue-group-head .button { margin-left: auto; }

/* ── 受眾改制 + 上載收窄（2026-08-12）──────────────────────────────────────────────────────
   一欄一個系統：Score code 欄帶埋佢自己個 sync state、Files 欄淨係音軌、擺位落 Task 欄。 */
.pa-row-meta { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 6px; vertical-align: middle; }
/* 受眾。繼承嗰啲淡色 —— 一眼分得出「呢個節點自己講嘅」定「跟阿爸」。
   🔴 斷行政策**得呢一條規則講**（S-2b §C）。之前有兩條：呢度「唔准斷」（樹行嗰陣要嘅），
      加上詳情框入面一條「准斷」嘅覆寫。兩條規矩同時存在，就等於冇一條講得死一件事 ——
      而樹行由 S-2a 起已經唔再 render 受眾，所以嗰個「唔准斷」嘅理由本身都冇咗。
      ⟹ 兩條一齊拆，剩返預設（可斷行）＋ 一個守尾門。
   `anywhere` 守尾門：層級名如果一個空格一個逗號都冇，靠標點斷行救唔到。 */
.pa-audience { flex: none; font: 10px var(--mono); color: var(--admin-deep); overflow-wrap: anywhere; }
.pa-audience.is-inherited { color: var(--ink-3); font-style: italic; }
/* 冇人見到 = 一個要睇得見嘅狀態，唔准淡到唔覺（fail-closed 唔等於靜靜）。 */
.pa-audience.is-empty { color: var(--danger); }

/* ── 樹狀連接線（2026-08-12）────────────────────────────────────────────────────────────────
   🔴 縮排**唔係**「level × 固定 px」—— 係逐層一格 `.pa-guide`，格數由 paCategoryTreeRows()
      個 walk 出（參差深度合法，幾深都自動）。線全部喺呢度用 ::before / ::after 畫，
      資料層一個字都冇為咗畫線而改。
   · 祖先仲有下一個兄弟 → `.is-line`，嗰格繼續有直線落嚟。
   · 最後一個仔 `.pa-guide-end`（└）：直線只去到中間就收。
   · 其餘 `.pa-guide-tee`（├）：直線穿過成格。 */
.pa-guides { display: flex; flex: none; align-self: stretch; }
.pa-guide { position: relative; flex: none; width: 16px; }
.pa-guide.is-line::before,
.pa-guide-tee::before {
  content: ""; position: absolute; left: 50%; top: 0; bottom: 0;
  border-left: 1px solid var(--line);
}
/* └ —— 直線去到橫枝就停，唔會再落。 */
.pa-guide-end::before {
  content: ""; position: absolute; left: 50%; top: 0; height: 50%;
  border-left: 1px solid var(--line);
}
.pa-guide-tee::after,
.pa-guide-end::after {
  content: ""; position: absolute; left: 50%; top: 50%; right: 2px;
  border-top: 1px solid var(--line);
}
/* 孤兒標示由 mono key 改成一句人話 —— key 而家係機器 derive 嘅，唔應該喺樹上同名爭位。 */
.pa-tree-name .pa-key { color: var(--danger); font-size: 10px; }

/* ── 葉右欄嗰張歌曲表（R-54 表格化）──────────────────────────────────────────────────────────
   ⚠️ 之前呢一區**一條 CSS 都冇**：由 6a 起，歌行同狀態 chip 嗰四個 class 全部冇定義過。
      後果唔止係難睇 —— 「音軌有」同「音軌冇」嗰兩個 class render 出嚟**完全一樣**，
      即係「有 MIDI 冇 XML」呢個狀態喺畫面上根本睇唔出，而 §6.6 視覺項 #4 就係要一眼
      分得出佢。⟹ 呢個係功能缺口，唔係美化。
      （⛔ 呢段唔寫返嗰四個 class 名 —— 佢哋已經死咗，寫喺度會令下一個 grep 嘅人以為仲用緊。）

   十欄唔窄，所以整張表**自己橫向捲**（`.pa-song-table-wrap`），⛔ 唔准畀成頁橫向捲 ——
   左邊棵樹會跟住郁走。 */
.pa-song-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); }
.pa-song-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.pa-song-table th,
.pa-song-table td { border-bottom: 1px solid var(--line); padding: 9px 10px; text-align: left; vertical-align: top; white-space: nowrap; }
.pa-song-table tbody tr:last-child td { border-bottom: 0; }
.pa-song-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: #fafafc; color: var(--ink-3);
  font-size: 10px; font-weight: 700; letter-spacing: .04em; white-space: nowrap;
}
/* 排序掣坐喺 th 入面，睇落要似個標題唔似個掣 —— 佢係一個 affordance，唔係一個動作。 */
.pa-sort {
  border: 0; background: transparent; padding: 0;
  color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit;
  cursor: pointer;
}
.pa-sort:hover { color: var(--admin-deep); }
.pa-song-table th.is-sorted { color: var(--admin-deep); }

/* 歌名格係唯一一格准 wrap 嘅 —— 歌名長度冇上限，逼佢一行只會撐爆成張表。 */
.pa-song-table .pa-col-name { white-space: normal; min-width: 190px; max-width: 320px; }
.pa-song-table .pa-col-name strong { display: block; font-size: 13px; line-height: 1.4; }
.pa-song-table .pa-col-name .pa-note { display: block; margin-top: 2px; line-height: 1.45; white-space: normal; }
.pa-song-table .pa-col-status { min-width: 132px; }
.pa-song-table .pa-col-status .badge { margin: 0 6px 0 0; }
.pa-song-table .pa-col-status .pa-note { display: block; margin-top: 3px; }
.pa-song-table .pa-col-num,
.pa-song-table .pa-col-tick { text-align: center; }
.pa-song-table .pa-col-num { font-variant-numeric: tabular-nums; }
.pa-song-table .pa-col-actions { text-align: right; }

/* muzix task 嗰啲行淡一格底色。⚠️ 唔用邊框／唔用色字 —— 兩池唔係「一個正常一個異常」，
   佢哋只係兩種嘢，所以呢度要嘅係**分組睇得出**，唔係其中一組被標記。 */
.pa-song-table tr.is-task { background: var(--soft); }

/* 三種「冇嘢」嘅視覺分工（同 pa-app.js 嗰段註釋一一對應）：
   · 一劃 = 有呢個概念但未有數 —— 淡，但睇得見。
   · 完全空白格 = 結構性冇 —— 冇任何字元，所以呢度冇 selector（**呢個係刻意**：
     一有 selector 就代表有人畫過嘢落去，而嗰格應該係真空）。
   · 0 = 真係零 —— 行返 .pa-num 個正常色，同一劃一眼分得開。 */
.pa-empty { color: var(--ink-3); }
.pa-num { color: var(--ink); }
.pa-stars { color: var(--admin-deep); letter-spacing: 1px; }
.pa-tick { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; color: var(--ink-3); }
.pa-tick.is-on { color: var(--success); font-weight: 700; }
.pa-tick-live { cursor: pointer; }
.pa-tick-live input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--admin-accent); }
.pa-song-legend { margin: 8px 2px 0; line-height: 1.6; }

/* ── 🔴 disabled 只准有一種樣（R-65）──────────────────────────────────────────────────────────
   ⚠️ 呢個唔係美觀問題，係**掃一眼會答錯**。

   基礎規則淨係褪色（opacity）＋ 換 cursor。褪色喺唔同尺寸／顏色嘅掣上面**讀出嚟嘅意思唔同**：
   一粒 9px 嘅細掣褪色之後讀作「熄咗」；一粒全尺寸粗體紅字嘅長掣褪同樣嘅色，讀落仍然係
   「紅色、可撳、只係淡咗少少」。⟹ 同一個狀態，兩種樣。而同事唔會逐粒 hover 去驗證 ——
   掃一眼就落判斷，跟住個判斷係錯嘅。（架構線睇圖都判錯過一次。）

   ⟹ 所以呢度**唔止褪色，連顏色一齊熄**：任何 disabled 掣一律變灰底灰字，
      無論佢本來係 primary、secondary 定 danger。「熄咗」要睇落係熄咗，唔係「淡咗嘅紅色」。

   🔒 收窄喺 `#pa-workspace` 內 —— muzix 側嘅 `.button:disabled` 一個 byte 都冇郁。
   ⚠️ 三樣嘢缺一不可：**褪色 ＋ not-allowed ＋ title**。頭兩樣喺呢度，title 喺 markup
      逐粒掣度畀（狀態軸嗰啲），有 test 掃住。 */
#pa-workspace .button:disabled,
#pa-workspace .button:disabled:hover {
  opacity: .5;
  cursor: not-allowed;
  border-color: var(--line);
  background: var(--soft);
  color: var(--ink-3);
  box-shadow: none;
}

/* ── 管理視窗（R-65：兩欄工作台）────────────────────────────────────────────────────────────
   🔴 佢由建歌 modal 長出嚟，而兩者係兩種嘢：建歌係**一次性表單**（由上到下填一次，
      填完就走）；管理視窗係**工作台**（開住喺度跳嚟跳去改嘢，而且做完唔會自動閂）。
      單欄直落對前者啱 —— 對後者就變成一條要不斷上下捲嘅長帶，而最常做嗰樣（上載音軌）
      同最少做嗰樣（改名）排喺同一條軸上面，冇分主次。
   ⟹ 改嘅係**佈局**，唔係將文字寫短。寫短係治標：同一堆嘢塞喺同一條軸，短咗一樣要捲。 */
/* ── 🔴 姊妹版面：建歌 modal ／ 管理視窗 ─────────────────────────────────────────────────────
   下面兩個 grid 係姊妹版面（建歌 / 管理），**斷點要一齊睇**。

   另開唔共用係明文決定（R-S2a，Henry b）：兩個 modal 語義唔同，會各自演化；綁死會製造
   「改 A 撞 B」。代價講清楚 = **兩個定義點**，改斷點要兩處一齊改 —— 所以佢哋貼住寫，
   唔准分開兩段，亦唔准中間插第三樣嘢。

   ⚠️ 兩者左欄擺嘅嘢唔同（一個係三個檔案位、一個係三條軌連掣），所以欄闊比例本來就
      唔應該一樣 —— 呢個就係唔綁死嘅理由本身。 */
.pa-form-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 18px; align-items: start; }
.pa-form-col-head { display: block; margin-bottom: 6px; color: var(--ink-3); font-size: 11px; font-weight: 700; }
.pa-form-col-files, .pa-form-col-meta { display: grid; gap: 12px; align-content: start; }
.pa-form-col-files .modal-field, .pa-form-col-meta .modal-field { margin: 0; }
.pa-upload-card:has(.pa-form-grid) { max-width: 720px; }
@media (max-width: 719px) { .pa-form-grid { grid-template-columns: minmax(0, 1fr); } }

.pa-manage-card { max-width: 720px; }
.pa-manage-cols { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.pa-manage-col-head { display: block; margin-bottom: 6px; color: var(--ink-3); font-size: 11px; font-weight: 700; }
/* 🔴 每格**併返一行**：揀檔嗰個 input 同兩粒掣做緊同一件事（處理呢條軌），拆兩行只係
   將一件事嘅高度乘二。左欄因此短三分一，而左欄就係最常用嗰欄。
   ⟹ 唔准 wrap；個 file input 收窄，畀掣有位。 */
.pa-manage-card .pa-track-line { flex-wrap: nowrap; gap: 10px; align-items: center; }
.pa-manage-card .pa-track-line > div:first-child { flex: 1; }
.pa-manage-card .pa-track-line-actions { flex-wrap: nowrap; align-items: center; }
.pa-manage-card .pa-manage-file { width: 132px; flex: none; font-size: 10px; }

/* 在／冇指示。⚠️ 佢係**唯一**一個一眼睇得出嘅分別（粒掣個 label 太細），所以實心／空心
   之外仲要色都唔同 —— 淨靠形狀，一堆細點排埋一齊分唔出。 */
.pa-track-flag { color: var(--ink-3); font-size: 10px; }
.pa-track-flag.is-on { color: var(--success); }

/* 個剔嘅貼身 label。整行都撳得（<label> 包住），所以 target 大好多。 */
.pa-tick-row { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.pa-tick-label { color: var(--ink-2); font-size: 11px; }

/* 🔴 狀態 badge **唔准睇落似一粒掣**。佢隔籬就係「出街／落架」，而兩者本來都係
   圓角小方塊 —— 視覺重量一樣，掃一眼會讀成兩粒掣。⟹ 剝走框同底，剩返色同字：
   **狀態係讀嘅，掣先係撳嘅。** */
.pa-manage-status-row .badge { border: 0; background: transparent; padding: 0; cursor: default; }
/* 右欄四塊嘢**各自一行**：歌曲狀態 / 只有搜尋可見 / 歌名 / 難度 係四條唔同嘅軸，
   ⛔ 唔准為咗慳位而撈埋一行或者共用同一組 chip（§6.4）。 */
.pa-manage-col-meta { display: grid; gap: 12px; }
.pa-manage-col-meta .modal-field { margin: 0; }
.pa-manage-status-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* type A 右欄剩返一格 —— 補一句講明其餘嘢住喺邊，否則睇落似個窗載漏咗嘢。 */
.pa-manage-elsewhere { border: 1px dashed var(--line); border-radius: 10px; padding: 10px 12px; }
@media (max-width: 719px) {
  .pa-manage-cols { grid-template-columns: minmax(0, 1fr); }
}

/* 底部：刪除喺左、收工掣喺右 —— 兩者中間有真空隙，唔會撳錯。 */
.pa-manage-foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; border-top: 1px solid var(--line); padding-top: 12px; }
.pa-manage-foot .modal-actions { margin: 0; }
/* 危險區唔用紅底 —— 個掣本身已經係 danger，成格再紅一次就變咗「呢個窗好危險」，
   而其實危險嘅只係嗰一粒掣。 */
.pa-manage-danger { min-width: 0; }
.pa-manage-log { margin: 10px 0 0; color: var(--ink-2); font-size: 11px; }
