/* 報表:月份 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`,再把寬度一格一格省出來(每一格的帳都記在下面那三段;沒有 ≤340 那一檔,
   字級的地板是 0.625rem):

     兩顆箭頭     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。
   **字級有地板:日期與「–」任何寬度、任何字級都不小於 0.625rem**(D-H80,舊 #812 ②)。
   在那個字級仍放不下的格(例如 320、或大字級的 `zoom: 1.15` 把版面寬縮小之後),
   不再縮字、也不截字,而是由 #610 的量測摺疊(`periodFit()`)把整列收成摘要鈕。 */
.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

   ⛔ **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; }
}

/* 大字級整段走最小那一檔(0.625rem,就是地板)— #592 第三輪起,第四輪重定成一個值。
   放不下就不再縮字,交給 #610 的量測摺疊(`periodFit()`)收成摘要鈕 —— #82。

   **媒體查詢看的是裝置寬,而 `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.625rem; padding: 8px 2px; }
  html[data-fsize="large"] .period label.f[for$="To"]::after { font-size: 0.625rem; }
}


.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` 給。留一條沒有人用的規則,下一個人會以為畫面上
   還有一段需要撐開的說明。 */

/* 已經退出這個帳本的人 — #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); }


/* 分類圓餅與圖例(`.rpcats` 那一組、`.rpcat`、`.rpdot`、`.rpname`)、空的圓
   (`.rppie-empty`)與 `.rpempty` 從 #112 起住在 home.css 的最後:首頁自己畫得出它們,
   而這支檔案是第二段(首頁畫出第一個數字之後才進文件)。 */

/* 兩張圓並排,底下一份圖例 — 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;
}
.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);
}


.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; }
/* 卡尾與它的 ? 同一列(#66):? 是卡的直接子節點,不包 foot,所以用 grid 並排。 */
#rpReceivableCard:not(.hide) { display: grid; grid-template-columns: minmax(0, 1fr) auto; }
#rpReceivableCard > * { grid-column: 1 / -1; }
#rpReceivableCard > #rpReceivableFoot { grid-column: 1; align-self: center; }
#rpReceivableCard > #rpRecvWhy { grid-column: 2; align-self: center; margin: -13px 0; }
#rpReceivableCard > #rpRecvWhy.hide { display: none; }
.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; }

/* 桌面 — #100(D-H82 / D-H43 2)。寬度走 --page-w;1200 起 #rpCards 站兩欄,
   期間卡(與提示列)橫跨兩欄,其餘卡片按文件順序自動排。 */
@media (min-width: 1024px) {
  #v-report { --page-w: var(--w-wide); }
}
@media (min-width: 1200px) {
  #rpCards { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 14px; align-items: start; }
  #rpCards > #rpMsg, #rpCards > #rpTimeCard { grid-column: 1 / -1; }
  /* 版位本身不佔格:卡在裡面就由卡入格,個人記帳卡搬走後版位是空的、不留空格。 */
  #rpCards > #rpSpendSlot { display: contents; }
}
