/* List toolbar · 清單頁頭的兩層控制骨架
   ────────────────────────────────────────────────────────────────────────
   2026-07-23 由 e-shop 的 `.eshop-list-topbar` / `.eshop-status-row` promote 而來（第一次被
   第二頁重用即 promote）。原始版型對齊 Figma node 845:11081／845:11082／671-2309。

   兩層結構（由上而下）：
     .list-toolbar        殼層工作列——實色 --surface-shell、四角 16px、固定 58px 高。
       └ .tabs              主軸 tab 撐滿容器高度，底線自然貼齊容器下緣
       └ .list-toolbar__actions   絕對定位靠右、垂直置中的動作群（搜尋／切換／主 CTA）
     .list-status-row     次層篩選列——透明、行內流，放 pill 篩選或 select

   為什麼工作列要固定高度＋align-items:stretch：tab 的 active 橘色底線貼在 .tabs__item 下緣，
   只有讓 tabs 撐滿整個 58px，底線才會落在容器最底部而不是浮在中間。

   消費者：e-shop（類型 tab ＋ 商店設定／預覽／建立分割按鈕）、projects（狀態 tab ＋ 搜尋／
   檢視切換／建立專案）。sticky 貼頂屬各頁捲動容器的版面決定，留在頁面 <style>，不進本檔。 */

.list-toolbar {
  position: relative;
  z-index: 6;
  display: flex;
  align-items: stretch;
  height: 58px;
  margin-bottom: var(--sp-8);
  /* 左右不對稱是刻意的（2026-07-26 使用者：建立鈕旁邊太擠）：左邊 8px 之外，第一個 tab
     自己還有 14px 內距，視覺留白其實是 22px；右邊的動作群沒有內距，8px 就會貼著邊。
     右側補到 20px 讓兩邊視覺對齊。 */
  padding-inline: var(--sp-8) var(--sp-20);
  background: var(--surface-shell);
  border-radius: var(--radius-xl);   /* 16px */
}
/* 淺色主題：--surface-shell 與頁面底色差在白天不夠讀，改白底＋卡片陰影撐出層次
   （比照低庫存通知條，2026-07-21 使用者反饋）。深色維持色差、不加陰影。 */
html[data-theme="light"] .list-toolbar {
  background: var(--card);
  box-shadow: var(--shadow-card);
}

/* tabs 吃掉動作群以外的所有寬度；min-width:0 讓它在窄容器下真的能縮
   （flex 子項預設 min-width:auto，不設 0 的話會撐破容器去撞右側動作群）。
   縮到裝不下時改成橫向捲動，捲軸隱藏——tab 數量各頁不同（e-shop 3 個、projects 6 個），
   不能假設塞得下。 */
.list-toolbar > .tabs {
  flex: 1 1 auto;
  min-width: 0;
  margin-bottom: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.list-toolbar > .tabs::-webkit-scrollbar { display: none; }
.list-toolbar .tabs__item {
  display: flex;
  align-items: center;
  white-space: nowrap;
}

/* 右側動作群：靠 margin-left:auto 推到底，不用絕對定位——絕對定位時 tabs 仍佔滿整條，
   tab 一多就會捲到動作群底下疊字（projects 6 個 tab 實測撞到）。 */
.list-toolbar__actions {
  flex: 0 0 auto;
  align-self: center;
  margin-left: auto;
  display: flex;
  gap: var(--sp-12);
  align-items: center;
}

/* 「更多篩選」鈕（2026-07-28）：只在貼頂且篩選段塞不下時出現，見下方
   .is-filters-collapsed。平時 display:none，所以靜止態的動作群完全不變。
   帶一顆計數徽章——收起來的東西如果正在生效卻看不出來，那不是收納是隱瞞。 */
.list-toolbar__filter {
  display: none;
  position: relative;
  flex: 0 0 auto;
}
.list-toolbar__filter-count {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--primary);
  color: var(--on-primary);
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  font-size: 10px;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}
.list-toolbar__filter-count[hidden] { display: none; }

/* 次層篩選列（pill 篩選或 select）。margin-bottom 是本列到清單的間距——
   2026-07-26 使用者指定加大（24→40），六個清單頁（專案／我的 IP／電子商店／訂單／取貨／活動）一致。 */
.list-status-row {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  flex-wrap: wrap;
  margin-top: var(--sp-16);
  margin-bottom: var(--sp-40);
}
/* 第一個 nav 吸收剩餘寬度，讓右側的 select 留在第一行：pill 多起來時（projects 的
   狀態列從 4 顆長到 7 顆）原本會整個 nav 換行、把 select 擠到第二行。改由 nav 自己
   內部 wrap，select 位置不動。min-width:0 讓它真的能縮。2026-07-27。 */
.list-status-row > nav:first-child {
  /* basis 0（不是 auto）才會真的縮到內容寬以下——auto 時 flex-shrink 從 641px 的內容
     寬算起，仍舊寬到把 select 擠掉。nav 自己是 flex-wrap:wrap，縮窄後 pill 內部換行。 */
  flex: 1 1 0;
  min-width: 0;
}
/* --end：把次層篩選推到右側（projects 的兩個下拉；e-shop 的狀態 pill 仍靠左）。 */
.list-status-row--end { justify-content: flex-end; }

/* 窄螢幕：工作列改直向堆疊、取消固定高度，動作群回到流內靠右 */
@media (max-width: 900px) {
  .list-toolbar {
    height: auto;
    flex-direction: column;
    align-items: stretch;
  }
  .list-toolbar__actions {
    width: 100%;
    margin-left: 0;
    margin-top: 10px;
    align-self: stretch;
    justify-content: flex-end;
    flex-wrap: wrap;
  }
}

/* ============================================================
   Snap dock（2026-07-28 使用者裁示）
   ------------------------------------------------------------
   使用者反饋三件事：(a) 我的 IP／IP 市場的工作列根本沒有貼頂；(b) 電子商店有貼頂
   但「很醜」；(c) 貼頂狀態要重新設計成盡量少佔空間，並用動畫轉場過去。

   為什麼原本只有電子商店會貼頂：sticky 一直被當成「各頁捲動容器的版面決定」寫在
   頁面 <style>（見本檔開頭），所以只有實作過的那一頁有。這次把它收進元件——貼頂是
   這個元件的行為，不是某一頁的巧合；收進來之後五個清單頁一次到位、也只有一份可調。

   原本貼頂的樣子（電子商店）：工作列 58px 實色卡 ＋ 16px 間距 ＋ 狀態列 44px 滿版
   底色，合計約 118px 永久佔住畫面上緣，兩塊各自為政、切換時沒有任何過渡。

   重新設計後的貼頂態（.is-snapped，由 js/sticky-dock.js 掛上）：
     · 兩排併成「一條」——外層 .list-dock 變 flex 橫排，工作列與狀態列同一行，
       中間一道 1px 分隔線。高度 58＋16＋44 → 44，省下約 6 成垂直空間。
     · 一整條變成浮起的 dock：半透明 --surface-shell ＋ backdrop blur（內容從底下
       捲過去時看得出層次，這裡的毛玻璃是為了「有東西在後面經過」而存在，不是裝飾），
       圓角、帶偏移與模糊的陰影。
     · 動畫：高度／內距／圓角／底色／陰影一起過渡，exponential ease-out。
       reduced-motion 下直接切換、不做過渡。
   ≤900px 不貼頂（沿用電子商店原本的桌機限定），窄螢幕垂直空間更珍貴，
   但一行塞不下 tabs＋動作群＋篩選，硬併會比不貼頂更糟。
   ============================================================ */

.list-dock__sentinel {
  height: 1px;
  margin-bottom: -1px;   /* 純量測用的哨兵，不佔版面 */
  pointer-events: none;
}

/* ── 貼頂時不要讓捲動位置被「捲動錨定」拉回去（2026-07-28）──────────
   使用者回報：電子商店往下捲到貼頂那一刻會彈來彈去，除非用力捲否則卡在那裡下不去。

   實測（Playwright，捲到 220 → 240）：
     220px：未貼頂，bars 高 106，文件高 3521
     240px：貼頂，  bars 高  71，文件高 3446   ← scrollTop 被改回 165
   兩排併成一行時整份文件矮了 75px，而瀏覽器的 scroll anchoring 為了讓「畫面上那一列
   商品看起來不要動」，把 scrollTop 往回拉了剛好 75px。結果是：捲過門檻 → 高度縮 →
   被拉回門檻上方 → 解除貼頂 → 高度長回來 → 再捲過去……在門檻附近來回震盪。
   「用力捲」＝一次跨過整個震盪帶，所以只有大力捲才過得去。

   關掉這個捲動容器的錨定即可：高度仍然會變（那正是貼頂要省下的空間），但捲動位置
   不再被回捲，門檻只會被穿過一次。:has() 把範圍限定在真的有貼頂列的清單頁，
   其他頁面的錨定行為不動。 */
.main:has(.list-dock) { overflow-anchor: none; }

/* 分工（2026-07-28 修，完整說明見 js/sticky-dock.js）：
     .list-dock        ＝ 可黏貼「範圍」。它可以很高、可以往下包住整個清單
                         （電子商店就是這樣，sticky 才黏得住整段捲動）。
                         它自己不 sticky，尤其不能在貼頂態變成 flex 容器。
     .list-dock__bars  ＝ 真正貼頂、真正變成 dock 的那一條。腳本在執行期包出來，
                         裡面只有 .list-toolbar ＋ .list-status-row。
   之前兩個角色由同一個 box 兼差，於是 `display:flex` 一下去，被那層包住的三個
   商品清單分頁也成了 flex item——工作列被壓成 124px、篩選 pill 直排，
   整個清單擠成一條窄柱（使用者回報的畫面）。角色分開就不會再發生。 */
@media (min-width: 901px) {
  /* sticky 掛哪一層，取決於這頁的殼包到哪裡（分類由 js/sticky-dock.js 掛 --tall/--thin）：
       厚殼（電子商店／活動，殼往下包住整個清單）→ 掛內層那一條，外層只當可黏貼範圍；
       薄殼（我的 IP／IP 市場／專案，殼只有兩排約 106px 高）→ 掛外層自己，
       因為 sticky 只能在親層 box 裡移動，掛內層的話捲過那 106px 就脫黏。
     只有厚殼那頁能用內層——這是上面那次修的前提，薄殼要補這條才會真的黏住。 */
  .list-dock--tall .list-dock__bars,
  .list-dock--thin {
    position: sticky;
    top: 0;
    z-index: 20;            /* 低於 app-topbar(50)，高於列 hover 的 z-index:1 */
  }

  .list-dock__bars {
    /* --radius-xl（16px）＝靜止態工作列卡的同一個圓角：貼頂後形狀是「同一張卡收窄」，
       不是換了一個新形狀。（初版寫 --radius-lg，實測只有 8px，讀起來像被裁掉的方條。） */
    border-radius: var(--radius-xl);
    transition:
      background-color 260ms cubic-bezier(.16, 1, .3, 1),
      box-shadow       260ms cubic-bezier(.16, 1, .3, 1),
      border-color     260ms cubic-bezier(.16, 1, .3, 1),
      /* 上圓角在貼頂時收成 0——一起過渡，否則會在轉場中途「啪」地換形狀 */
      border-radius    260ms cubic-bezier(.16, 1, .3, 1);
  }

  /* 貼頂態：整條 dock 自己是那張卡，內層兩排都變透明、併成一行。 */
  .list-dock.is-snapped .list-dock__bars {
    display: flex;
    align-items: center;
    gap: var(--sp-14);
    /* 一行到底，不換行。試過「塞不下就讓篩選段掉到第二行」，但專案頁實測會回到 106px
       ——與靜止態同高，等於這個貼頂態一點空間也沒省，那就沒有存在的理由了。
       控制項多的頁面改由各段自己橫向捲（見下方 .list-status-row 的 overflow-x），
       並在右緣加一道漸隱提示還有東西。 */
    flex-wrap: nowrap;
    padding: var(--sp-6) var(--sp-16);
    /* 94% 而不是 86%：清單列從底下捲過去時，只差 14% 明度的半透明面板會和列糊在一起，
       讀不出「這條在前面」。毛玻璃在這裡是為了讓底下的移動看得見一點，不是要看穿。 */
    background: color-mix(in srgb, var(--surface-shell) 94%, transparent);
    backdrop-filter: blur(14px) saturate(140%);
    /* 上緣切平（2026-07-28 使用者裁示：「拿掉貼頂態的上圓角，讓它看起來是頁首外框的延伸」）。
       貼頂之後這一條的上緣正好切齊頁面外框的內側——留著 16px 圓角就會在兩個角各露出一小塊
       底色，讀起來像一張「浮在框裡的卡」；切平之後它是那個外框往下長出來的一段。
       下緣的圓角留著：下面是會捲動的內容，那一側仍然是這條自己的邊界。 */
    border-radius: 0 0 var(--radius-xl) var(--radius-xl);
    /* 下緣要有一條實線：捲動的內容正好從這裡通過，沒有邊界就沒有「上面／下面」。 */
    border-bottom: 1px solid var(--border);
    box-shadow: 0 6px 20px -10px rgb(0 0 0 / 0.5);
  }
  html[data-theme="light"] .list-dock.is-snapped .list-dock__bars {
    background: color-mix(in srgb, var(--card) 94%, transparent);
    box-shadow: 0 6px 20px -12px rgb(0 0 0 / 0.28);
  }

  /* 工作列在 dock 裡讓出背景與圓角——那些現在歸 dock 管，避免卡中卡。 */
  .list-dock.is-snapped .list-toolbar {
    height: 44px;
    margin-bottom: 0;
    padding-inline: 0;
    background: transparent;
    border-radius: 0;
    box-shadow: none;
    /* 0 1 auto（不是 1 1 auto）：這一段先照內容寬拿到空間，剩下的才給篩選段。
       兩段都能捲的時候必須決定「誰先被犧牲」——主軸 tab（發行模式）與主要動作
       （＋新增專案）是這一頁的骨架，狀態 pill 是可篩可不篩的細節。
       實測未分優先序時，四個模式 tab 的「直接發行」被捲出畫面，那是最不該藏的東西。 */
    flex: 0 1 auto;
    min-width: 0;
  }

  /* 狀態列收成 dock 右段：去掉自己的留白與底色，用一道分隔線和左段分開。
     篩選數量各頁不同（電子商店 5 個、IP 市場 4 個），塞不下就在自己那段橫向捲。 */
  .list-dock.is-snapped .list-status-row {
    /* 1 1 0：吸收工作列拿完之後剩下的寬度，也是先被壓縮的那一段（理由見上）。 */
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
    /* 這一列自己不換行：它要嘛整段留在第一行右側、要嘛整段掉到第二行（由上面 bars 的
       flex-wrap 決定），中間狀態（下拉自己折下去、pill 留在上面）讀起來只是壞掉。 */
    flex-wrap: nowrap;
    padding: 0 0 0 var(--sp-12);
    border-left: 1px solid var(--border);
    /* 右緣漸隱：這一段塞不下時會橫向捲，沒有這道提示，被捲在外面的篩選等於不存在。
       遮罩只吃右緣 24px，捲到底時仍然會有一小段淡出——那是可接受的代價，
       換來的是「這裡還有東西」這個訊息一直都在。 */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .list-dock.is-snapped .list-status-row::-webkit-scrollbar { display: none; }
  /* 貼頂時篩選 nav 改「照內容寬」，不再吸收剩餘寬度（2026-07-28 修）。
     基礎樣式給它 flex:1 1 0（basis 0）是為了靜止態讓右側的下拉留在第一行；但併成一行
     之後那條規則會把 nav 壓到接近 0 寬，而 nav 自己沒有 overflow、內容又被設成 nowrap
     ——於是 pill 直接畫到後面的下拉上面（專案頁實測：「Live 8」與「All categories」
     疊字，使用者回報）。改成 0 0 auto：nav 撐回內容寬，塞不下就由外層 .list-status-row
     的 overflow-x 橫向捲——那本來就是這個貼頂態設計好的退路。 */
  .list-dock.is-snapped .list-status-row > nav:first-child { flex: 0 0 auto; }
  /* 篩選群本身要不換行——併成一行後右段寬度有限，預設的 flex-wrap 會讓 pill 折成兩排
     （IP 市場實測 4 顆 pill 折行後整條 dock 從 57px 變 83px，等於白省了）。
     改成不換行＋外層橫向捲：塞不下就用捲的，高度永遠是一排。 */
  .list-dock.is-snapped .list-status-row > * {
    flex-wrap: nowrap;
    white-space: nowrap;
  }

  /* ══ 塞不下時怎麼辦（2026-07-28 L：「how do we fix this problem when theres too
        many sub nav? use a filter icon to expand? and i want all those sub nav to
        stick to the right when there are enough space」）══════════════════════

     問題：貼頂態把兩排併成一排之後，專案頁要在同一行放 4 個模式 tab ＋ 3 個動作
     ＋ 7 顆狀態 pill ＋ 1 個分類下拉＝13 個可點目標。橫向捲＋24px 漸隱是目前的
     退路，但實測就是把「Cancelled」從字中間切斷（L 截圖），而且捲動這件事在一條
     只有 44px 高的 bar 上沒有人會發現。這條縫已經補過三次（pill 疊到下拉上、
     模式 tab 被捲出畫面），每一次都只是把不足換個地方，因為 13 個目標本來就放不下。

     兩段式，由 sticky-dock.js 量測後掛 class：
       放得下 → 篩選段靠右（margin-left:auto），與左邊的主軸拉開距離；
       放不下 → 整段收進一顆 sliders 圖示鈕，點開變成錨在鈕下方的浮層。

     為什麼是 margin-left:auto 而不是 justify-content:flex-end：
     兩者「放得下」時看起來一樣，但溢出時 flex-end 會讓內容往左邊溢出，先被藏起來的
     是最左邊的「All states」，而且橫向捲會從中間開始。auto margin 在空間不足時
     自動塌成 0，溢出方向與捲動起點都維持正常。

     為什麼收合只發生在貼頂態：狀態 pill 帶著計數（All states 16／Draft 1／Live 8），
     那些數字是「一眼看完」的資訊，全部藏進圖示等於把它丟掉。靜止態的兩排版面空間
     充足、該全部顯示；貼頂態那條 bar 的工作是「讓你知道自己在哪、還能動手」，
     不是當儀表板——那裡才值得收。

     圖示沿用站上既有的 sliders-horizontal 進階篩選鈕（ip-market #ipm-adv-toggle、
     e-shop 同款），不自創第二種「更多篩選」的長相。 */

  /* 放得下：靠右。nav 是 .list-status-row 的第一個子元素，右邊還有分類下拉。 */
  .list-dock.is-snapped .list-status-row > nav:first-child { margin-left: auto; }

  /* 放不下：整段變成錨在篩選鈕下的浮層。用「移動同一個節點」而不是複製一份，
     所以 id、事件、計數更新全部沿用原本那一套，沒有第二份要同步。 */
  .list-dock.is-snapped.is-filters-collapsed .list-status-row {
    display: none;
    position: absolute;
    top: calc(100% + var(--sp-8));
    right: var(--sp-16);
    z-index: 30;
    width: max-content;
    max-width: min(560px, calc(100vw - var(--sp-32)));
    flex-wrap: wrap;
    padding: var(--sp-12);
    border: 1px solid var(--border);
    border-left: 1px solid var(--border);   /* 蓋掉貼頂態那條左分隔線 */
    border-radius: var(--radius-lg);
    background: var(--popover, var(--card));
    box-shadow: var(--shadow-float, 0 12px 32px -12px rgb(0 0 0 / 0.5));
    /* 浮層裡不需要橫向捲與右緣漸隱——它有自己的寬度可以換行 */
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .list-dock.is-snapped.is-filters-collapsed .list-status-row > nav:first-child {
    margin-left: 0;
    flex-wrap: wrap;
  }
  .list-dock.is-snapped.is-filters-collapsed .list-status-row > * { flex-wrap: wrap; }
  .list-dock.is-snapped.is-filters-collapsed.is-filters-open .list-status-row { display: flex; }
  /* bars 要能當浮層的定位參考 */
  .list-dock.is-snapped .list-dock__bars { position: relative; }

  /* 篩選鈕只在收合時出現 */
  .list-dock.is-snapped.is-filters-collapsed .list-toolbar__filter { display: inline-flex; }

  /* 只過渡 height 一個版面屬性（padding／margin 改成瞬間切換）。
     detect.mjs 會標 layout-transition：動版面屬性會觸發重排。這裡刻意保留 height——
     它是「收合」這個動作本身，拿掉就變成瞬間跳一格、L 要的轉場就不存在了；
     而且這是捲動方向改變時才跑一次的一次性過渡、只作用在一個元素上，
     不是逐幀動畫，重排成本是一次而非每幀。padding/margin 對觀感沒有貢獻，故移出。 */
  .list-dock.is-snapped .list-toolbar,
  .list-dock.is-snapped .list-status-row {
    transition: height 260ms cubic-bezier(.16, 1, .3, 1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .list-dock,
  .list-dock .list-toolbar,
  .list-dock .list-status-row { transition: none; }
}
