/* 報表:月份 chips、分類佔比的圓餅、各人的水平長條、餘額曲線 — FR-9。
 *
 * 長條全部是原生 div 的寬度百分比;圓餅是手寫 SVG(#238,理由在 report.js 的
 * drawCategories 上面 —— uPlot 沒有圓餅,而它是這個專案唯一的第三方)。
 * **兩張圖都由 vendored uPlot 畫 — #203**
 * (#148 只換了累積支出,餘額曲線留著手寫 SVG,於是同一頁上有兩套外觀);顏色
 * 仍然一格都沒有搬家 —— 那幾條 `.rpspend .lN` 是給 JS 讀的探針,見下面。 */

/* 報表分頁進來第一眼那個當月淨支出 — #144。
   F17 到 #143 之間它是首頁上一顆整條可按的折疊標題:`.rphead` 是 button(手機上
   按得到的面積),右邊一顆 `.rpchev` 箭頭跟著 aria-expanded 轉。報表變成自己的
   分頁之後沒有東西要折疊,剩下的只是一個標題與一個數字,那三組規則因此退役。 */
.rphead-id { min-width: 0; }
.rphead-id .big { display: block; }

/* 頁首那**兩列** — D-F74(使用者裁示 2026-09-03)收成兩列於 #556(D-H29 §1:
   「報表 2 列還不錯」)。

   **月份步進器(`.rpstep` / `.rparrow`)與月份 chips(`#rpMonths`)那五條規則在
   D-F74 退役;第三列那一整組(`.rppicks` / `.rppicks button` /
   `.rppicks button[aria-pressed="true"]` / `.rppicks:empty`)與第一列舊的
   `.rpmodes` 在 #556 跟著它們的節點一起退役。** 留一條沒有人用的規則,下一個人會
   以為畫面上還有那一列。

   兩列在 390px 上疊起來約 96px:第一列五顆籤(44,同 `.seg` 那條全站下限)、第二
   列翻頁或兩格日期(44)。D-F74 那一版是三列約 150px —— 收掉的整整是一列。 */

/* 第一列:五顆籤 — `role="tablist"`(#505 併入 #556)。
   樣子與 `.seg` 那組**同一種**:同一個 app 裡「選一個」只准有一種長相
   (style.css 的 `.seg button[aria-pressed="true"]` 就是那一份),差別只在選中的
   那一格答的是 `aria-selected` 而不是 `aria-pressed` —— 換掉的是語意,不是外觀。

   **會換行不會橫捲**:五顆籤在 390px 上放得下一行,使用者把字放大之後折成兩行,
   而每一顆都仍然整顆看得見。D-F74 那一列之所以要橫捲,是因為它有二十幾格。 */
.rptabs { display: flex; flex-wrap: wrap; gap: 8px; }
.rptabs button {
  font: inherit; font-size: 0.8125rem; line-height: 1;
  padding: 9px 12px; min-height: 44px;
  color: var(--ink); background: var(--chip);
  border: 1px solid transparent; border-radius: var(--radius-pill);
  white-space: nowrap; cursor: pointer;
}
.rptabs button[aria-selected="true"] {
  background: var(--card); border-color: var(--accent); color: var(--accent);
  font-weight: 600;
}
/* 鍵盤走到哪裡要看得見 — #495 / #505(併入 #556)。**讀 `--ring` 不是
   `var(--accent)`**:那一格是這個 app 的焦點框接縫,而繞過它的唯一寫法就是在
   `:focus-visible` 的規則裡寫回主色(test_web 的 TheFocusRingReadsItsOwnToken 守
   的正是這個)。`:focus-visible` 而不是 `:focus`:用手指點的人不需要一圈跟著手指
   跑的框。 */
.rptabs button:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

/* 第二列:`‹ 從 [日期] 到 [日期] ›` 一列 — #591。標記住在 `web/period.js`
   (`periodHTML()`),紀錄頁(#592)共用同一份,所以樣式也只有這一份 —— 兩頁各抄
   一份的下場是同一列控制在兩頁上折行的時機不一樣。

   `#556` 那一版是兩份節點(翻頁與兩格日期),中間那一格 `.rppagenow` 寫著現在停在
   哪一段;兩格日期本來就永遠寫著同一件事,所以那一格連同 `.rppage` / `.rpsp-dates`
   一起退場。

   ## ⛔ 它**不換行** — #592 第三輪(主線裁示 2026-09-20)

   #591 那一版是 `flex-wrap: wrap`,理由寫著「390px 上一行放得下整列,再窄一點就折
   成兩行」。**實測不是那樣**:390 上它就折了(`›` 掉到第二行,整列 96px),而使用
   者原話是「只要用一列 `‹ 從Day 到day ›`」—— 折成兩行就不是一列。紀錄頁(#592)
   還替它算出了第二筆帳:那 96px 讓第一屏從 9 列掉到 7 列,而 D-H29 §1 釘著 ≥9。

   所以 `nowrap`,再把寬度一格一格省出來(每一格的帳都記在下面那三段):

     兩顆箭頭     44×44 不動 —— 那是 D-F100 的 `TAP_MIN`,不是一個可以省的數字
     兩格日期     `flex: 1 1 0` + `min-width: 0` —— 分掉剩下的,而且**可以縮到比
                  內容窄**(`1 1 110px` 的 110 基底正是 390 上折行的那一下)
     「從」「到」  ≤480 視覺收掉(節點留著:`<label for>` 仍然是那一格的可及名稱),
                  中間留一個「–」讀得出這是一段區間
     日曆記號     ≤480 收掉 `::-webkit-calendar-picker-indicator`(省 17px,實測)
                  —— 手機上點那一格本來就會開挑選器,那顆記號是桌機的入口

   實測的自然寬度(Chrome,`input[type=date]` 要多寬才不截字,`value=2026-09-20`):

     0.8125rem / padding 6px   130px(收掉日曆記號後 113)
     0.75rem   / padding 4px   117px(收掉後 101)
     0.625rem  / padding 2px    97px(收掉後  83)

   對上每一格真的分到多少(390 / 360 / 320,標準字級,實測):116 / 106 / 86 ——
   三格都比它那一檔要的寬。**唯一放不下的是 320 × 大字級**(`zoom: 1.15` 把版面寬
   算成 278,每格只剩 66):那一格日期會被截幾個字元,而裁示是「320 寬允許縮字級、
   不允許折行」—— 它仍然是一列、仍然不橫捲(實測 `scrollWidth - clientWidth = 0`)。 */
.period {
  display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; margin-top: 10px;
}
.period label.f { flex: none; margin: 0; }
.period input {
  flex: 1 1 0; width: auto; min-width: 0; padding: 8px 6px; font-size: 0.8125rem;
}

/* 手機那一檔:把兩個字的標籤與日曆記號的寬度省下來給日期本身 — #592 第三輪,
   **字級的排程在第四輪照 Firefox 重排了**(見底下那一段)。

   **標籤收的是字級不是節點**:`display: none` 會讓 `<label for>` 不再是那一格的
   可及名稱,而讀屏要唸得出「從」;`font-size: 0` 的節點仍然在無障礙樹上。
   中間那個「–」掛在「到」那一格身上(`[for$="To"]`,兩個呼叫端的前綴都以它結尾),
   所以畫面上讀得出這是**一段**而不是兩個各自為政的日期。

   ## 字級為什麼是這幾格 — #592 第四輪(兩個引擎一起量)

   `input[type=date]` 要多寬才不截字**是引擎的性質,不是我們的**,而 Firefox 比
   收掉記號的 Chrome 寬 **17–18px**(實測,padding 4px,`value=2026-09-20`,版面 px):

       0.75rem    Chrome 101 / Firefox 119      0.625rem/2  83 / 100
       0.5625rem/2 Chrome  76 / Firefox  93

   ⛔ **Firefox 那一邊拿不掉那 18px**:`::-webkit-calendar-picker-indicator` 在它上面
   是一條沒有人讀的規則,而 `-moz-appearance: textfield` / `appearance: textfield`
   對寬度**一格都不動**(實測:四種寫法逐格相同)。它的寬度是內部那串 `yyyy/mm/dd`
   撐出來的,不是一顆拿得掉的鈕 —— **所以對 Firefox 唯一的槓桿是字級**,下面這三檔
   就是照它排的;Chrome 因此在每一檔都多出 20px 以上的餘裕。

   `gap` 從 6 收到 4 也是同一筆帳:五個 gap 省 10px、兩格日期各多 5px,而那 5px
   正好是 390 上 Firefox 從「差 3」變成「有餘 2」的那一步。 */
@media (max-width: 480px) {
  .period { gap: 4px; }
  .period label.f { font-size: 0; }
  .period label.f[for$="To"]::after {
    content: "–"; font-size: 0.75rem; color: var(--dim);
  }
  .period input { font-size: 0.75rem; padding: 8px 4px; }
  /* Chrome / Safari 的那顆日曆記號收掉 —— 省 17px(實測)。手機上點那一格本來
     就會開挑選器,那顆記號是桌機的入口。Firefox 沒有這一條(見上面)。 */
  .period input::-webkit-calendar-picker-indicator { display: none; }
}
@media (max-width: 370px) {
  .period input { font-size: 0.625rem; padding: 8px 2px; }
  .period label.f[for$="To"]::after { font-size: 0.625rem; }
}
@media (max-width: 340px) {
  .period input { font-size: 0.5625rem; padding: 8px 2px; }
  .period label.f[for$="To"]::after { font-size: 0.5625rem; }
}

/* 大字級整段走最小那一檔 — #592 第三輪起,第四輪重定成一個值。

   **媒體查詢看的是裝置寬,而 `zoom` 縮的是版面寬**(prefs.css:
   `html[data-fsize="large"] { zoom: 1.15 }`),所以同一個 390 在大字級底下只剩
   339 的版面 —— 上面那三檔一格都不會多挑,而每一格日期少了十幾 px。`data-fsize`
   是那件事**唯一問得到的訊號**:媒體查詢問不到 zoom,`vw` 也不跟著縮(prefs.css
   那一段逐字記著)。

   ⚠️ **量的單位要對齊**:`getBoundingClientRect()` 回的是**縮放後**的 px,而
   `font-size` 與上面那張需求表是**縮放前**的版面 px —— 兩者直接相比會把大字級那
   幾格算寬 15%(#592 第三輪的 EVIDENCE 就是這樣把 320 × 大字級寫成「放得下」的,
   第四輪已更正)。底下的餘裕全部換算回版面 px 之後才比。 */
@media (max-width: 480px) {
  html[data-fsize="large"] .period input { font-size: 0.5625rem; padding: 8px 2px; }
  html[data-fsize="large"] .period label.f[for$="To"]::after { font-size: 0.5625rem; }
}


.period .pprev, .period .pnext {
  flex: none; font: inherit; font-size: 1.125rem; line-height: 1;
  min-width: 44px; min-height: 44px; padding: 0;
  color: var(--ink); background: var(--chip);
  border: 1px solid transparent; border-radius: var(--radius-pill);
  cursor: pointer;
}
/* 放不下時的那一顆摘要 — #610。**摺不摺由 `periodFit()`(web/period.js)量了才
   寫上 `data-fold`**,這裡沒有斷點:放得下的那一列一個像素都不變(`.psum` 平常是
   `display: none`)。

   摺起來是三格:`‹ [摘要] ›`;點摘要(`data-open`)在下面多兩行「從 [日期]」
   「到 [日期]」,日期佔滿標籤之外的寬,字級回到桌機那一檔 —— 這兩行不再跟箭頭搶
   一列,而截字正是上面那幾檔縮字級要躲的事。標籤的字也回來(一列時它們收成
   `font-size: 0`,見上面),中間那個「–」用不到了。 */
.period .psum { display: none; }
.period[data-fold] {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
}
.period[data-fold] .pprev { grid-area: 1 / 1; }
.period[data-fold] .psum {
  grid-area: 1 / 2; display: block; min-width: 0; min-height: 44px; padding: 0 8px;
  font: inherit; font-size: 0.875rem; color: var(--ink); background: var(--chip);
  border: 1px solid transparent; border-radius: var(--radius-pill);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
}
.period[data-fold] .pnext { grid-area: 1 / 3; }
.period[data-fold] label.f, .period[data-fold] input { display: none; }
.period[data-fold][data-open] label.f {
  display: block; grid-column: 1; font-size: 0.8125rem; text-align: center;
}
.period[data-fold][data-open] label.f[for$="To"]::after { content: none; }
.period[data-fold][data-open] input {
  display: block; grid-column: 2 / 4; width: 100%;
  font-size: 0.8125rem; padding: 8px 6px;
}

/* 到了兩端那一顆是真的 `disabled`(F3),而它要看得出來按不下去 —— `cursor` 也
   跟著換:一個還是手指的游標會讓人以為自己按錯地方了。 */
.period .pprev:disabled, .period .pnext:disabled {
  color: var(--dim); opacity: 0.5; cursor: default;
}
/* 鍵盤走到哪裡要看得見 — #495 / #591 裁示 6。**四樣都在 tab order 裡**(兩顆箭頭
   與兩格日期),所以四樣都要有框;三條規則分開寫而不是一條逗號串起來,因為
   test_web 那份守衛逐字指名選擇器,而一個沒有被寫出來的焦點框是靜默的。 */
.period .pprev:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.period .pnext:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.period input:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.period .psum:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

/* `.rpspaced` 跟著它唯一的使用者退役 — #249:月報卡上那段「支出減退款…」收進
   標題旁邊的問號裡(`.bal-sheet`,樣式在 home.css),而紙裡的段距由
   `.bal-sheet .muted + .muted` 給。留一條沒有人用的規則,下一個人會以為畫面上
   還有一段需要撐開的說明。 */
.rpname { font-weight: 600; }

/* 已經退出這個帳本的人 — #249。`by_member` 從 #203 起帶著他(不然 Σ承擔 ≡ 淨支
   出會破),但那一列上看不出他是誰。**是一段字不是一個色點**:色點在這一頁上
   已經是分類的語言(`.rpdot`),而「已離開」是一句話,單色列印也讀得出來。 */
.rpleft { margin-left: 6px; font-size: 0.75rem; }

/* 戶頭自己付掉的那一列 — #249。**它與人的那幾列同一種版型**(同一個 `.rpmem`
   格子、同一把尺),因為它答的是同一個問題的最後一格:這個月的錢是誰先出的。
   名字用 dim 是唯一的差別 —— 它不是一個人,而那件事在「墊付」這種字眼旁邊要看
   得出來,不然它會被讀成一位叫「家用帳戶」的成員。
   **待分攤那一列同理 — #299**,一併吃這條規則:它也不是一個人,「承擔」旁邊要
   看得出來它是還沒分掉的那一份,不是漏列的一個成員。 */
.rpdirect .rpname, .rpunassigned .rpname { color: var(--dim); }

/* 共用的長條:外框是槽,<i> 是填色。overflow 收邊,免得填滿時圓角被切方。 */
.rpbar {
  height: 8px; border-radius: var(--radius-pill);
  background: var(--chip); overflow: hidden;
}
.rpbar i { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--accent); }

/* 分類佔比:一個圓環加一份圖例 — #238。**橫條那三條規則跟著退役**(`.rpcat .row`
   / `.rpcat .rpbar` / `.rpcat .muted` 的左邊距);`.rpbar` 本體留著,各人那張卡
   還在用它。

   **圓是 SVG,顏色是 `currentColor`。** 每一塊 `<circle>` 與圖例上的色點共用同一
   組 `.cN`,所以「這一塊是哪個顏色」在畫面上只有一份答案;那六個 token 就是
   style.css 既有的六個資料色(累積支出的四條 lane 加兩條餘額線用的也是它們)——
   這裡不長出第二套配色,深色模式也因此自己會跟。

   選擇器以 `.rpcats` 開頭,同這支檔案底下 `#rpSpend` / `#rpChart` 那一組的理由:
   `.c0` 這種名字太泛,而 view 的 css 是掛在整份文件上的。

   ⚠️ **它以前以那個 id 開頭,而那在 #243 變成了一個 bug。** 那一票讓同一份圓環
   多一個版位(個人記帳首頁的 `#rpSoloCats`),而 id 選擇器只認得原本那一個 ——
   **沙盒實測(390×844,chromium 頭無介面,2026-08-24)首頁畫出來的是一個全黑的
   圓**:`fill: none` 沒生效所以整個圓被填滿,六個 `.cN` 也沒生效所以圖例的色點是
   白的。作用域換成兩個版位共有的那個 class,而它與 id 一樣把 `.c0` 關在裡面。 */
.rpcats .rppie { display: block; width: 176px; height: 176px; margin: 14px auto 8px; }
/* stroke 畫在路徑兩側:半徑 40、粗 17,所以圓環佔 31.5–48.5,離 viewBox 邊還有
   1.5 的餘裕。`fill: none` 少一個字,中間那個洞就會被填成黑色。 */
.rpcats .rppie circle { fill: none; stroke: currentColor; stroke-width: 17; }
/* 六塊的顏色在 #392 換成 `--chart-1` … `--chart-6`。**它們以前借的是六個語意
   token**(accent / warn / cash / settled / ink / dim)—— 而借的代價是「這一塊
   是餐飲」與「這一格是警告」同色,換一個主題就要重驗一次那六個湊在一起好不好
   看。現在它們是一組專門為了「同一張圖上要分得開」而定的序列色,五個主題各一
   份,兩兩的 OKLab 距離由 test_web.TheBalanceLinesStayApartInEveryTheme 守著。

   **同一組色同時是成員色**(fmt.js 的 swatchOf):同一個人在首頁的色塊與在報表
   圓餅上本來就該是同一個顏色。 */
.rpcats .c0 { color: var(--chart-1); }
.rpcats .c1 { color: var(--chart-2); }
.rpcats .c2 { color: var(--chart-3); }
.rpcats .c3 { color: var(--chart-4); }
.rpcats .c4 { color: var(--chart-5); }
.rpcats .c5 { color: var(--chart-6); }

/* 圖例:一列一類 —— 色點、分類名、金額、百分比。四欄格子而不是 `.row`,金額與
   百分比才對得齊(名字長短不一,靠 flex 的話右邊兩格會各自浮在不同的位置)。 */
.rpcat {
  display: grid; grid-template-columns: auto 1fr auto auto;
  align-items: baseline; gap: 2px 10px;
  padding: 11px 0; border-bottom: 1px solid var(--line);
}
.rpcat:last-child { border-bottom: 0; }
/* 點得下去的那幾列是真的 `<button>` — #249(分類下鑽)。**不是掛 onclick 的
   div**:鍵盤走得到、讀屏唸得出「按鈕」,而那是這個 app 裡「看起來可以按」與
   「真的可以按」同一件事的唯一寫法。

   按鈕自己帶一圈邊框與置中的字,所以三樣要收掉再把底線加回去(`.rpcat` 那條
   `border-bottom` 會被 `border: 0` 一起吃掉);`font`/`color` 要 inherit —— 少
   了它們,同一份圖例在報表分頁上會突然變成系統字。
   排在 `.rpcat` 之後:同特異度時後到的贏,而這幾條是覆寫。 */
.rpcats button.rpcat {
  width: 100%; font: inherit; color: inherit; text-align: left;
  background: none; border: 0; border-bottom: 1px solid var(--line);
  cursor: pointer;
}
/* 右邊那顆「›」多一欄 — #516。它說的是「這一列有地方可去」(D-H6),取代的是那張
   問號紙上被刪掉的那一句導覽提示。字級與顏色同首頁結算指令那一列的 `.fl-go`
   —— 同一個記號在這個 app 裡只有一種樣子。`.rpmerged` 照舊 `2 / -1`,多出來的那
   一欄它自己會算進去。 */
.rpcats button.rpcat { grid-template-columns: auto 1fr auto auto auto; }
.rpcat-go { flex: none; font-size: 0.8125rem; color: var(--dim); }
.rpcats button.rpcat:last-child { border-bottom: 0; }
.rpdot {
  width: 10px; height: 10px; border-radius: 3px;
  align-self: center; background: currentColor;
}
/* 進不了圓餅的那幾類:**空心**。實心的色點會讓人在圓上去找一塊不存在的顏色,
   而右邊那一格已經寫著它沒有進圖。 */
.rpcats .rpdot.off { background: none; border: 1px dashed var(--dim); }
/* 「其他」那一列底下的分類名 —— 併的是塊不是資料,名字要留在畫面上。跨到整列
   的右端,與名字切齊。 */
.rpmerged { grid-column: 2 / -1; font-size: 0.75rem; }

/* 兩張圓並排,底下一份圖例 — D-F76(#314,個人記帳分類圓餅成對)。
 * 樣式與 home.css 的 .pie-pair 逐字相同。 */
.pie-pair { display: flex; gap: 12px; margin-top: 12px; }
.pie-tab {
  flex: 0 0 calc(50% - 6px); min-width: 0;
  padding: 8px 4px 10px; font: inherit; color: inherit; text-align: center;
  background: none; border: 1px solid transparent; border-radius: var(--radius-m);
  cursor: pointer;
}
.pie-tab[aria-pressed="true"] { background: var(--chip); border-color: var(--line); }
.pie-tab .rpcats .rppie {
  width: 100%; height: auto; aspect-ratio: 1; margin: 0 auto 6px;
}
.rppie-empty {
  display: block; width: 100%; height: auto; aspect-ratio: 1; margin: 0 auto 6px;
}
.rppie-empty circle {
  fill: none; stroke: var(--dim); stroke-width: 2; stroke-dasharray: 5 4;
}
.pie-name { display: block; font-size: 0.78125rem; color: var(--dim); }
.pie-tab .num { display: block; margin-top: 2px; font-size: 0.9375rem; }

/* 各人:三欄格子 —— 標籤、長條、金額。兩列共用同一組欄寬,承擔與墊付的長條
   起點與終點才會對齊,不然「同一個尺規」就只是嘴上說說。 */
.rpmem { padding: 12px 0; border-bottom: 1px solid var(--line); }
.rpmem:last-child { border-bottom: 0; }
.rpduo {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 8px 10px; margin-top: 8px;
}
.rpduo .k { font-size: 0.75rem; color: var(--dim); }
.rpduo b { font-size: 0.8125rem; text-align: right; white-space: nowrap; }
/* 墊付那條長條的藍在 #259 進了主題契約(`--paid`,web/themes.css)—— 同 log.css
   `.tag.in` 的那一支:本來寫死在這裡、自己帶一句 media query,而主題鎖定之後那種
   寫法會在淺色系統鎖暗色時留在亮色的值上。

   **#556 起它讀 `--chart-1`(D-H29 §1 裁示 5)。** `--chart-paid` 原本是圖表那六
   個序列色之外自己一格,而那一格的工作是「墊付」這個**類別**;D-H29 把圖表色改成
   單色階梯之後,這一頁上剩下的序列色只有一條 —— 這排長條答的是「各人之間誰多誰
   少」,而那正是 `--chart-1` 這一格(對比由 EveryThemeMeetsContrast 的
   `--chart-1/--card` 那一列量)。`--chart-paid` 本身沒有刪:主題契約那 83 格是一
   份整體,少一格要整批主題一起改,而那不是這一票的事。 */
.rpduo i.paid { background: var(--chart-1); }

/* 排序長條 — #556(D-H29 §1)。選擇器不以 `.rpcats` 開頭:`web/rank.js` 是一支
   共用元件,#557 要在首頁上 import 同一支,而一條只在報表底下才生效的規則會讓那
   一票在首頁上畫出一排沒有樣式的 div。它住在 report.css 是因為今天只有這一頁畫得
   出它(同 `.rpname` 當年借給圖例的那一條),而兩支 view css 都是全站掛載的
   `<link>`(index.html 那一排)。

   **一列四格**:名字 / 百分比 / 金額 / 軌。前三格是 `auto`,軌吃掉剩下的寬度 ——
   軌是這一列上唯一「越長代表越多」的東西,所以它要是最有彈性的那一格。
   390px 上名字那一格會被長名字撐開,`min-width: 0` + `text-overflow` 讓它省略而
   不是把軌擠成零寬。 */
.rankrow {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center; gap: 2px 10px;
  padding: 10px 0; border-bottom: 1px solid var(--line);
}
.rankrow:last-child { border-bottom: 0; }
.rankrow .rpname { min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.rankpct { font-size: 0.8125rem; }
/* 軌**跨滿整列**(第二行),不是擠在金額旁邊的一小格:一條 60px 的軌上,12% 與
   9% 差 1px。 */
.ranktrack {
  grid-column: 1 / -1; height: 9px; margin-top: 2px;
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  overflow: hidden;
}
/* 軌底是**透明**的,不是一條灰底 — D-H29 §1 裁示 2:填滿的那一段讀的是
   `--rank-N` 對 `--card` 的對比(PAIRS 那四列量的就是它),而一條灰底會在它與填
   色之間再開一組沒有人量過的對比。 */
.ranktrack i { display: block; height: 100%; }
/* 單色階梯 — `--rank-1` 最暗(第一名),越往下越亮。**第 5 名起重用 `--rank-4`**
   (`rank.js` 的 `RANK_STEPS` 把 index 夾在那裡),理由是再往下分階明度差會掉到
   看不出來,而一條看不出差別的階梯比重用一階更會騙人(themes.css 的 `--rank-*`
   那一段寫著同一句話)。 */
.ranktrack i.r1 { background: var(--rank-1); }
.ranktrack i.r2 { background: var(--rank-2); }
.ranktrack i.r3 { background: var(--rank-3); }
.ranktrack i.r4 { background: var(--rank-4); }
/* 付款那張卡跟人不跟名次 — #663(DESIGN-POOL-HOME §3.1)。`rank.js` 的 `tone` 在
   那幾條軌上帶 `--bar`(成員色 / `--ledger-pool`,`<i>` 繼承);分類那一排不帶,照
   舊 rN。 */
#rpPayersCard .ranktrack { --bar: var(--dim); }
#rpPayersCard .ranktrack i { background: var(--bar, var(--dim)); }
/* 標題旁那一句「這段期間沒有支出」—— 合計是 0 卻有列的時候才有字,其餘時候它不
   該佔一格寬度(`.bal-name` 是 flex)。 */
.rankzero { font-size: 0.8125rem; }
.rankzero:empty { display: none; }
/* 折疊列 — `<button aria-expanded>`,一整列寬:它是一列的延伸,不是一顆浮在旁邊
   的鈕。觸控目標 44(全站下限,D-F100)。 */
.rankmore {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; min-height: 44px; margin: 0; padding: 10px 0;
  font: inherit; font-size: 0.8125rem;
  color: var(--dim); background: none; border: 0; cursor: pointer;
}
.rankmore:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
/* 點得下去的那幾列(分類長條)是 `<button>`:按鈕自己帶一圈邊框與置中的字,所以
   三樣要收掉再把格線加回去 —— 判準與寫法逐字同 `.rpcats button.rpcat`。 */
button.rankrow {
  width: 100%; margin: 0; text-align: left;
  background: none; border: 0; border-bottom: 1px solid var(--line);
  font: inherit; color: inherit; cursor: pointer;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
}
button.rankrow:last-child { border-bottom: 0; }
button.rankrow:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }

/* 累積支出:一條線畫一段日子,x 軸是日期(一格一天)— D-F61。
   顏色全部取 style.css 既有的變數(這裡不長出第二套配色);**顏色不是唯一的分
   辨方式** —— 三條線是三種線形,每條在 legend 上還有自己的名字,單色列印或色覺
   不同的人也讀得出哪條是哪條。

   **#148 之後這幾條規則是給 JS 讀的,不是給瀏覽器畫的。** 圖改由 uPlot 畫在
   canvas 上,而 canvas 吃不到 var() —— report.js 的 laneColours() 掛一組
   `.rpspend > .lN` 的探針進 DOM、問 getComputedStyle、再拿掉。所以「線色定義在
   哪裡」一個字都沒有搬:還是這裡,還是那四個 token,深色模式也還是自己會跟。 */
/* **只剩一條 lane — D-F61。** 這裡原本有四條(`.l0`–`.l3`):月份疊圖時一個月一
   條線,月份多過四條就從頭輪。日期軸那一版只有一條支出線,那三格因此沒有任何消
   費者 —— 留著它們,下一個人會照著以為這張圖還會疊。`report.js` 的 `LANES` 是同
   一件事的另一半(探針掛幾格由它長出來)。 */
.rpspend .l0 { color: var(--accent); }
/* 疊在同一組軸上的兩條餘額線 — #182。它們不輪 lane(各自永遠只有一條),所以
   各自一格;顏色是 style.css 新開的第五、第六個資料色,理由寫在那裡。 */
.rpspend .lbal { color: var(--chart-cash); }
.rpspend .lset { color: var(--chart-settled); }
/* 探針只被 getComputedStyle 問一次就拿掉,但它在 DOM 裡的那一瞬間不該佔位、不
   該被看見。**不能用 display:none** —— 那會讓 color 以外的東西不再解析,而下一
   個人加一條需要版面的規則時會踩到。 */
.rpprobe { position: absolute; width: 0; height: 0; overflow: hidden; visibility: hidden; }

/* uPlot 的樣式表是 vendor 原檔(位元組與上游相同,才驗得起 sha256),裡面的顏色
   是它自己的預設:十字線 #607D8B、選取框半透明黑。接上專案 token 的工作在這裡
   做,不去改那個檔。

   **選擇器一律以 #rpSpend / #rpChart 開頭。** vendor 那條 <link> 是 report.js 動態
   附加的,排在 head 裡所有靜態 stylesheet 之後,同分時後到的贏;用 id 拉高一個級
   距,載入順序就不再是必須記住的事。**兩個 id 一組規則 — #203**:餘額曲線也是
   uPlot 了,而「兩張圖看起來是同一套東西」該是同一段 CSS,不是兩段抄得很像的。 */
#rpSpend .uplot, #rpChart .uplot { width: 100%; font-family: inherit; }
/* 只有直線 —— `.u-cursor-y` 那半跟著 #155 一起走:那個元素現在根本不會被建出來
   (`cursor.y: false`),留一條指不到東西的規則,下一個人會以為畫面上有它。 */
#rpSpend .u-cursor-x, #rpChart .u-cursor-x { border-color: var(--dim); }
#rpSpend .u-select, #rpChart .u-select { background: var(--chip); }
/* legend 就是長按/停留時讀值的地方:一列一條線,欄是日期 / 當日增減 / 到當天為
   止。數字靠右並用等寬數字,三條線疊起來時位數才對得起來。 */
#rpSpend .u-legend, #rpChart .u-legend {
  margin: 10px 0 0; font-size: 0.78125rem; color: var(--ink);
  text-align: left; width: 100%;
}
#rpSpend .u-legend th, #rpSpend .u-legend td,
#rpChart .u-legend th, #rpChart .u-legend td { padding: 3px 0 3px 10px; }
#rpSpend .u-legend th:first-child, #rpSpend .u-legend td:first-child,
#rpChart .u-legend th:first-child, #rpChart .u-legend td:first-child { padding-left: 0; }
#rpSpend .u-legend thead th, #rpChart .u-legend thead th { color: var(--dim); font-weight: 500; }
/* ⚠️ `.u-value` 就是那個 <td>,不是它裡面的東西 —— 給它 display:block 會把整列
   拆成三行疊起來(實測過)。要動的只有對齊與字形。 */
#rpSpend .u-legend .u-value, #rpChart .u-legend .u-value {
  font-variant-numeric: tabular-nums; text-align: right;
}

/* 累積支出的標題列 — #182:「累積支出」與那個月累積到現在多少,同一列的兩端。
   金額比報表那張卡的 38px 小,而且與餘額卡並排那兩個**同一級(20px)**:首頁
   上這是第三個大數字,三個同級才讀得出「這一頁有三塊」。實測 26px 時
   NT$70,872 會比餘額卡的 NT$34,520 更搶眼,而那個順序是反的。 */
.rpsp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.rpsp-head h3 { flex: none; }
/* 標題與它的問號同一組 — #220,同餘額卡那兩顆的 `.bal-name`。整組不收縮:收縮
   的話「累積支出」會先被折成兩行,而問號要貼在字尾不是貼在卡緣。 */
.rpsp-head .bal-name { flex: none; }
.rpsp-head .big { font-size: 1.25rem; margin: 0; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
/* 時間區間:這條線畫的是哪一段,不是那個月有幾天。 */
.rpsp-span { margin-top: 2px; font-size: 0.78125rem; }
.rpsp-span:empty { display: none; }
/* 圖底下那句話在 #220 收進標題旁邊的問號裡(`.bal-sheet`,樣式在 home.css
   ——「一張彈出來的紙」在這個 app 裡只有一種樣子,#216 就定了),所以 `.rpsp-key`
   那條規則跟著退役。 */

/* 兩張圖共用的外框。**手寫曲線那四條規則跟著它一起退役 — #203**:線色、零軸的
   虛線、圓點現在都由 uPlot 畫在 canvas 上(顏色從上面那組探針讀)。名字刻意不
   在這裡重打一次 —— `test_home_chart` 掃的是「整支檔案裡還有沒有那幾個字」。 */
.rpchart { margin-top: 10px; }

.rpnote {
  display: flex; justify-content: space-between; gap: 12px;
  margin-top: 8px; font-size: 0.75rem; color: var(--dim);
}

.rpempty {
  margin-top: 12px; padding: 16px; text-align: center;
  background: var(--chip); border-radius: var(--radius-m); font-size: 0.8125rem; color: var(--dim);
}

.rpmsg { margin-top: 10px; font-size: 0.8125rem; color: var(--dim); }
.rpmsg:empty { display: none; }

/* 帳本應收款 — #663(DESIGN-POOL-HOME §3.2 / §3.3)。一人一條軌,軌長 m、分段
   用 flex 權重(欄位值原樣,寬度由瀏覽器分),空的那段是軌底。顏色只准是 token。 */
.rprv-asof { font-size: 0.8125rem; margin-bottom: 4px; }
.rprv-foot { font-size: 0.8125rem; margin-top: 8px; }
.rprv-foot:empty, .rprv-asof:empty { display: none; }
#rpReceivableState:empty { display: none; }
.rprv { border-bottom: 1px solid var(--line); }
.rprv:last-child { border-bottom: 0; }
.rprv-head, .rprv-text {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 4px 8px; width: 100%;
  padding: 10px 0; min-height: 44px;
  background: none; border: 0; color: inherit; font: inherit; text-align: left;
}
.rprv-head { cursor: pointer; }
.rprv-head:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
.rprv-dot { width: 10px; height: 10px; border-radius: 50%; }
.rprv .rpname { min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.rprv-state { font-size: 0.8125rem; text-align: right; }
.rprv-state.pay { color: var(--warn); }
.rprv-nm, .rprv-parts { grid-column: 1 / -1; font-size: 0.8125rem; }
.rprv-track {
  grid-column: 1 / -1; display: flex; height: 9px; min-width: 0;
  border-radius: var(--radius-pill); overflow: hidden; background: var(--chip);
}
.rprv-track i { display: block; flex-basis: 0; flex-shrink: 1; min-width: 0; }
.rprv-track i.paid { background: var(--chart-paid); }
.rprv-track i.released { background: var(--ok); }
.rprv-track i.offset { background: var(--ok); }
.rprv-track i.advance { background: var(--ledger-pool); }
.rprv-track i.gap { background: var(--chip); }
.rprv-over {
  grid-column: 1 / -1; justify-self: end; font-size: 0.75rem;
  padding: 1px 6px; border-radius: var(--radius-pill); background: var(--ok-soft);
}
.rprv-detail { padding: 0 0 10px 18px; }
.rprv-line { display: flex; justify-content: space-between; gap: 8px;
  font-size: 0.8125rem; padding: 2px 0; }
