/* 2026-05-28 設計 token 收斂:
   - 模組縮圖統一兩種尺寸 (.ipcs-module-thumb / .ipcs-module-thumb-sm) — 取代各頁面 inline style
   - 品牌 LOGO 預覽 (.ipcs-brand-logo-preview) — 取代 inline width/height/bg/radius */
.ipcs-module-thumb {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: var(--bs-border-radius, 8px);
  flex-shrink: 0;
}
.ipcs-module-thumb--trial-ended {
  filter: grayscale(0.5);
  opacity: 0.7;
}
.ipcs-module-thumb-lg {
  width: 56px;
  height: 56px;
  border-radius: var(--bs-card-border-radius, 12px);
  background-size: cover;
  background-position: center;
  flex-shrink: 0;
}
.ipcs-brand-logo-preview {
  width: 32px;
  height: 32px;
  object-fit: contain;
  background: #fff;
  border-radius: var(--bs-border-radius-sm, 4px);
  padding: 2px;
}
.ipcs-brand-mark-img {
  object-fit: contain;
  background: #fff;
  border-radius: var(--bs-badge-border-radius, 6px);
  padding: 2px;
}

.ipcs-page-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 24px;
  padding: 32px;
  margin-bottom: 24px;
  border: 1px solid var(--bs-border-color);
  border-radius: 12px;
  background:
    radial-gradient(circle at top right, rgba(182, 146, 88, 0.1), transparent 28%),
    var(--bs-card-bg);
  box-shadow: var(--pc-card-box-shadow);
}

.pc-sidebar .navbar-wrapper {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.pc-sidebar .navbar-content {
  flex: 1 1 auto;
  min-height: 0;
  padding-bottom: 8px;
}

.ipcs-sidebar-card {
  margin: 0 16px 18px;
  padding: 18px;
  border: 1px solid rgba(170, 183, 194, 0.4);
  border-radius: 12px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(247, 250, 252, 0.96)),
    radial-gradient(circle at top right, rgba(182, 146, 88, 0.08), transparent 28%);
  box-shadow: 0px 8px 24px rgba(41, 52, 74, 0.08);
}

.ipcs-avatar {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 18px;
  background: linear-gradient(135deg, #233548, #43586f);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 12px 28px rgba(35, 53, 72, 0.2);
}

/* 同 `.ipcs-ws-avatar__img`:2026-09-21 起 AUTH 的 `iconUrl` 不再保證是正方形,
   `cover` 會把橫式 logo 左右切掉而且完全沒有錯誤訊號。理由詳見那一段的註解。 */
.ipcs-avatar__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: inherit;
}

.ipcs-topbar-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  min-width: 360px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid rgba(216, 224, 231, 0.92);
  box-shadow: 0 10px 24px rgba(20, 36, 52, 0.04);
}

.ipcs-topbar-pill__copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ipcs-topbar-pill__copy small {
  color: #4f6070;
  font-size: 0.72rem;
  line-height: 1;
  letter-spacing: 0.06em;
}

.ipcs-topbar-pill__copy strong {
  color: #233548;
  font-size: 1.02rem;
  line-height: 1.15;
  font-weight: 700;
}

.ipcs-sidebar-user-card .user-avtar {
  object-fit: cover;
}

.ipcs-profile-dropdown {
  min-width: 250px;
}

.ipcs-profile-dropdown .dropdown-item,
.ipcs-profile-dropdown .dropdown-item-text {
  display: flex;
  align-items: center;
  gap: 10px;
}

.ipcs-profile-dropdown .dropdown-item-text {
  padding: 0.85rem 1rem 0.35rem;
  color: #4a5c6b;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.ipcs-profile-dropdown .dropdown-item i {
  font-size: 1rem;
}

.ipcs-sidebar-user-card {
  margin: 16px;
  margin-top: auto;
  border: 1px solid rgba(170, 183, 194, 0.32);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(247, 250, 252, 0.98));
  box-shadow: 0 16px 34px rgba(25, 43, 63, 0.06);
  flex-shrink: 0;
}

.ipcs-sidebar-user-card__subtitle {
  display: block;
  margin-top: 2px;
  color: #4a5c6b;
}

/* sidebar 底部使用者卡的「⋯」帳號選單 (鏡像 topbar 頭像 dropdown) */
.ipcs-sidebar-user-menu__btn {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: #5a6b7a;
  font-size: 1.1rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.ipcs-sidebar-user-menu__btn:hover,
.ipcs-sidebar-user-menu__btn[aria-expanded="true"] {
  background: rgba(4, 169, 245, 0.1);
  color: var(--bs-primary, #04A9F5);
}
.ipcs-sidebar-user-menu__dropdown {
  margin: 0;
}
body[data-pc-theme='dark'] .ipcs-sidebar-user-menu__btn { color: #748892; }
body[data-pc-theme='dark'] .ipcs-sidebar-user-menu__btn:hover,
body[data-pc-theme='dark'] .ipcs-sidebar-user-menu__btn[aria-expanded="true"] {
  background: rgba(4, 169, 245, 0.18);
  color: #5dc3f8;
}

.ipcs-sidebar-upgrade-card {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px;
  margin-top: auto;
  padding: 14px 16px;
  border-radius: 18px;
  border: 1px solid rgba(4, 169, 245, 0.32);
  background: linear-gradient(135deg, rgba(4, 169, 245, 0.08), rgba(4, 169, 245, 0.02));
  color: #1b4d71;
  text-decoration: none;
  box-shadow: 0 12px 28px rgba(4, 169, 245, 0.1);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
  flex-shrink: 0;
}

.ipcs-sidebar-upgrade-card:hover,
.ipcs-sidebar-upgrade-card:focus {
  transform: translateY(-1px);
  border-color: rgba(4, 169, 245, 0.56);
  box-shadow: 0 18px 38px rgba(4, 169, 245, 0.18);
  color: #04618e;
  text-decoration: none;
}

.ipcs-sidebar-upgrade-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: rgba(4, 169, 245, 0.14);
  color: #04A9F5;
  font-size: 1.25rem;
  flex-shrink: 0;
}

.ipcs-sidebar-upgrade-card__copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex-grow: 1;
  min-width: 0;
}

.ipcs-sidebar-upgrade-card__copy strong {
  font-size: 0.95rem;
  color: #1b4d71;
  line-height: 1.2;
}

.ipcs-sidebar-upgrade-card__copy small {
  font-size: 0.72rem;
  color: #5a6b7a;
  line-height: 1.3;
}

.ipcs-sidebar-upgrade-card__chevron {
  color: #04A9F5;
  font-size: 0.9rem;
  flex-shrink: 0;
}

.ipcs-brand-lockup {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  color: inherit;
  text-decoration: none;
}

.ipcs-brand-copy {
  display: inline-flex;
  flex-direction: column;
  gap: 3px;
}

.ipcs-brand-copy strong {
  font-size: 1.15rem;
  letter-spacing: 0.08em;
  color: #17283a;
}

.ipcs-brand-copy small {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: #4a5c6b;
}

.ipcs-auth-brand-block .ipcs-brand-copy strong,
.ipcs-auth-brand-block .ipcs-brand-copy small {
  color: #17283a;
}

/* 品牌字顏色跟「側邊欄主題」走,不跟頁面主題走(brand-copy 住在側邊欄裡)。
   這樣「頁面淺色 + 側邊欄深色」或「頁面深色 + 側邊欄淺色」都能維持對比,不會看不到。
   scope 到 .pc-sidebar 才不影響 auth 頁的 .ipcs-auth-brand-block。 */
[data-pc-sidebar-theme='dark'] .pc-sidebar .ipcs-brand-copy strong {
  color: var(--pc-sidebar-color, #ffffff);
}

/* 2026-08-28:原本是 #748892,在深色側邊欄底 #1d2630 上只有 4.14:1,沒過 WCAG AA 的 4.5:1。
   換成 CLAUDE.md 對「深色模式次要文字」規定的 #b0bec5(同底色 8.03:1)。
   這一格是品牌鎖定的次行,下游子系統會照抄 —— 錯的值抄出去就是一整批系統一起不合規。 */
[data-pc-sidebar-theme='dark'] .pc-sidebar .ipcs-brand-copy small {
  color: #b0bec5;
}

.ipcs-brand-mark {
  width: 54px;
  height: 54px;
  flex-shrink: 0;
}

/* LUXOR 字標 lockup — 圖左、標語文字右,垂直置中對齊(繼承 .ipcs-brand-lockup 的 row + align-items:center) */
.ipcs-brand-lockup--wordmark {
  gap: 12px;
}

/* 字標高度自適應(2026-08-28)。原本寫死 32px —— 在 1080p 以上的螢幕看起來偏小,
   而側邊欄本身是固定寬,再大的螢幕它也不會跟著長。
   clamp 的三個值:
     36px  下限 —— 比原本的 32px 大一級,窄螢幕/手機也不再更小
     3.4vw 中段 —— 跟著視窗寬走(1280px→43.5px、1600px→54px→被上限收住)
     52px  上限 —— 側邊欄寬約 260px,字標寬高比 400:170≈2.35,
                   52px 高≈122px 寬,約佔側邊欄一半,再大就開始擠掉左右留白
   width:auto 保持等比,不會變形(品牌規範 §3.4:不得非等比縮放)。 */
.ipcs-brand-wordmark {
  height: clamp(36px, 3.4vw, 52px);
  width: auto;
  display: block;
  flex-shrink: 0;
}

/* 預設(淺色側邊欄)顯示黑字版,白字版藏起來 */
.ipcs-brand-wordmark--dark {
  display: none;
}

/* 深色側邊欄切到白字版;登入頁 / 工作區頁改白底,改用預設黑字版 (使用者 2026-07-06) */
[data-pc-sidebar-theme='dark'] .pc-sidebar .ipcs-brand-wordmark--light {
  display: none;
}

[data-pc-sidebar-theme='dark'] .pc-sidebar .ipcs-brand-wordmark--dark {
  display: block;
}

/* 工作區頁字標放大 */
/* 工作區頁:全寬內容頁,不受側邊欄寬度限制,所以區間比側邊欄大一級。 */
.ipcs-ws-header .ipcs-brand-wordmark {
  height: clamp(40px, 4.2vw, 64px);
}

/* 登入頁左側品牌字標放大 (標語已移除,字標為唯一品牌元素);白底改黑字版 + 淺陰影 */
/* 登入頁左欄:字標是這頁唯一的品牌元素,區間最大。
   下限 84px 是「在 1366×768 的筆電上仍撐得起左欄」的值,不是隨手取的。 */
.ipcs-auth-brand-block .ipcs-brand-wordmark {
  height: clamp(84px, 8.4vw, 132px);
  filter: drop-shadow(0 6px 16px rgba(27, 46, 94, 0.12));
}

.ipcs-auth-brand-block .ipcs-brand-lockup--wordmark {
  gap: 18px;
}

/* 側邊欄品牌區的高度預算(2026-08-31 修)。
   模板原生是 .pc-sidebar .m-header { height:74px; padding:16px 24px } → 內容區只有 42px,
   而 .b-brand 原本又自己吃掉 12+6=18px 的上下 padding → 真正留給字標的只有 24px。
   字標是 clamp(36px,3.4vw,52px),所以**一直都超出**,dev220.0.557 把上限從 32 拉到 52 之後更明顯
   (溢出 8px → 28px,會壓到下方 .navbar-content)。

   修法與 IPCS_會議管理 團隊回報的一致:**header 總高 74px 不動**,只把 padding 讓出來 ——
   .navbar-content 的 calc(100vh - 149px) 是按 74px 算的,改 height 會讓側欄與主內容對不齊。
   74 - (11*2) = 52px,剛好等於字標的 clamp 上限;.b-brand 的上下 padding 一併歸零。 */
.pc-sidebar .m-header {
  padding: 11px 24px;
}

.pc-sidebar .m-header .b-brand {
  display: flex;
  align-items: center;
  /* 側邊欄 LOGO 置中 (使用者 2026-07-06);b-brand 撐滿 m-header 內容區才能真正水平置中 */
  justify-content: center;
  width: 100%;
  padding: 0;
  height: auto;
}

.pc-sidebar .m-header .ipcs-brand-copy strong {
  font-size: 1rem;
}

.ipcs-auth-shell {
  min-height: 100vh;
  position: relative;
  overflow: hidden;
}

/* 語言切換器(POC) — 模板無此元件,自訂 ipcs- prefix;pill 用模板 primary #04A9F5 */
/* 選擇器要帶 .auth-main.v2 提高 specificity:模板 `.auth-main.v2 > *{position:relative}` (0,2,0)
   會壓過裸 `.ipcs-auth-lang`(0,1,0),害語言切換器變成 in-flow flex item 佔走左側橫向空間、
   把登入卡擠出右緣(手機被 overflow:hidden 裁掉)。帶上 .auth-main.v2 後 (0,3,0) 才壓得回 absolute。 */
.auth-main.v2 .ipcs-auth-lang {
  position: absolute;
  top: 18px;
  right: 22px;
  z-index: 6;
}

/* 切換器改用 ph-translate 圖示下拉,跟登入後 topbar 一致(使用者 2026-06-15)。
   toggle 是半透明圓鈕(深色圖示)疊在白色背景上;dropdown-menu 沿用模板 .pc-h-dropdown 樣式。 */
.ipcs-auth-lang-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 999px;
  background: rgba(27, 46, 94, 0.05);
  border: 1px solid rgba(27, 46, 94, 0.12);
  backdrop-filter: blur(6px);
  color: #46586a;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}

.ipcs-auth-lang-toggle:hover,
.ipcs-auth-lang-toggle[aria-expanded="true"] {
  color: #17283a;
  background: rgba(27, 46, 94, 0.1);
}

.ipcs-auth-shell .bg-overlay {
  background:
    linear-gradient(150deg, #ffffff 0%, #f6f9fc 55%, #eef4f9 100%),
    radial-gradient(circle at 80% 16%, rgba(4, 169, 245, 0.06), transparent 42%),
    radial-gradient(circle at 14% 86%, rgba(4, 169, 245, 0.04), transparent 46%);
  opacity: 1;
}

/* 全屏裝飾 — 整塊背景一致 (左右沒分塊感),
   網格紋從左到右延伸,光暈在右下角 */
.ipcs-auth-shell::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(135deg, rgba(4, 169, 245, 0.04), transparent 45%),
    repeating-linear-gradient(90deg, transparent 0, transparent 31px, rgba(27, 46, 94, 0.035) 31px, rgba(27, 46, 94, 0.035) 32px),
    repeating-linear-gradient(0deg, transparent 0, transparent 31px, rgba(27, 46, 94, 0.035) 31px, rgba(27, 46, 94, 0.035) 32px);
  pointer-events: none;
  z-index: 1;
}

.ipcs-auth-shell::after {
  content: "";
  position: absolute;
  right: -120px;
  bottom: -160px;
  width: 480px;
  height: 480px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(4, 169, 245, 0.10), transparent 68%);
  pointer-events: none;
  z-index: 1;
}

.auth-main.v2.ipcs-auth-shell > .auth-wrapper {
  position: relative;
  z-index: 2;
}

.auth-main.v2.ipcs-auth-shell .auth-wrapper {
  display: grid;
  min-height: 100vh;
  width: 100%;
  align-items: stretch;
  grid-template-columns: minmax(360px, 0.95fr) minmax(460px, 560px);
}

.auth-main.v2.ipcs-auth-shell-wide .auth-wrapper {
  grid-template-columns: minmax(360px, 0.92fr) minmax(760px, 1.2fr);
}

.auth-main.v2.ipcs-auth-shell .auth-sidecontent {
  position: relative;
  width: 100%;
  padding: 56px;
  display: flex;
  align-items: stretch;
  justify-content: flex-start;
  overflow: hidden;
  /* 拿掉 auth-sidecontent 自己的 background — 與右側 (auth-form) 共用同一個 bg-overlay 暗藍漸層,
     避免左側因雙層 background 看起來比右側深;左側仍透過 ::before / ::after 裝飾保有層次。 */
  background: transparent;
}

/* auth-sidecontent ::before / ::after 已搬到 .ipcs-auth-shell::before/::after (全屏覆蓋),
   讓網格紋 + 光暈延伸到右側,整塊背景一致無分塊感 */

.ipcs-auth-panel {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.ipcs-auth-brand-block {
  max-width: 460px;
}

.auth-main.v2.ipcs-auth-shell .auth-form {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 44px 28px;
}

.auth-main.v2.ipcs-auth-shell .auth-form .card {
  width: 100%;
  max-width: 560px;
  border: 1px solid rgba(216, 224, 231, 0.95);
  border-radius: 12px;
  box-shadow: 0px 8px 24px rgba(41, 52, 74, 0.12);
  min-height: auto;
}

.auth-main.v2.ipcs-auth-shell .auth-form .card-body {
  padding: 32px;
}

.auth-main.v2.ipcs-auth-shell-wide .auth-form {
  align-items: flex-start;
  padding: 40px 36px;
}

.auth-main.v2.ipcs-auth-shell-wide .auth-form .card {
  max-width: 100%;
}

/* ── Subscription management list ── */

/* ── Step Wizard (Pricing) ── */

@media (max-width: 767.98px) {
  .auth-main.v2.ipcs-auth-shell .auth-sidecontent {
    display: none;
  }
}

/* ── 登入頁垂直排版:品牌 ICON 置頂、表單卡置中(使用者 2026-07-13)──
   把原本左右兩欄 grid 改成單欄垂直置中:品牌在上、登入卡在中間。
   只套用在 Login(_IpcsAuthLayout 帶 IpcsAuthStacked 旗標);App WebView 模式
   (.ipcs-in-app)不套用,維持既有單屏鎖定排版。 */
.auth-main.v2.ipcs-auth-shell-stacked .auth-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 48px 20px;
}

.auth-main.v2.ipcs-auth-shell-stacked .auth-sidecontent {
  width: auto;
  min-height: 0;
  padding: 0;
  overflow: visible;
  flex: 0 0 auto;
}

.auth-main.v2.ipcs-auth-shell-stacked .ipcs-auth-panel {
  height: auto;
}

.auth-main.v2.ipcs-auth-shell-stacked .ipcs-auth-brand-block {
  padding: 0 24px 8px;
}

/* 直式堆疊(平板/窄視窗):改成連續值,但**上限維持 84px 不放大** ——
   下方那條註解記著 2026-08-08「手機版登入頁 LOGO 佔掉半個畫面」的事故,
   這一段的數字是那次調出來的,只往下給彈性、不往上加。 */
.auth-main.v2.ipcs-auth-shell-stacked .ipcs-auth-brand-block .ipcs-brand-wordmark {
  height: clamp(64px, 9vw, 84px);
}

.auth-main.v2.ipcs-auth-shell-stacked .auth-form {
  width: 100%;
  padding: 0;
  flex: 0 0 auto;
}

.auth-main.v2.ipcs-auth-shell-stacked .auth-form .card {
  max-width: 460px;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}

/* SSO / Google 回呼的錯誤卡**不是** `.card`(它是自己的 `.ipcs-sso-error-card`),
   所以上面那條抓不到它,而它自帶 `margin: 80px auto` ——
   在 stacked 版面下會在品牌與卡片之間多撐出 80px 的空白。
   ⚠️ 2026-09-21 這兩頁才改成 stacked(以前走左右雙欄,那個 margin 是對的),
   所以這條規則是**跟著版面一起改的**,不是多餘的修補。 */
.auth-main.v2.ipcs-auth-shell-stacked .auth-form .ipcs-sso-error-card {
  margin-top: 0;
  margin-bottom: 0;
}

/* 手機:品牌 ICON 仍置頂(蓋掉上面把 auth-sidecontent 隱藏的規則,靠 source order 勝出) */
@media (max-width: 767.98px) {
  .auth-main.v2.ipcs-auth-shell-stacked .auth-sidecontent {
    display: flex;
  }

  /* 手機:同樣只往下給彈性,上限維持 64px(見上方事故註記)。 */
  .auth-main.v2.ipcs-auth-shell-stacked .ipcs-auth-brand-block .ipcs-brand-wordmark {
    height: clamp(48px, 13vw, 64px);
  }
}

/* ⚠ 手機版登入頁「LOGO 佔掉半個畫面」的修正(使用者 2026-08-08 回報)。
 *
 * 病灶不是這裡的規則寫錯,而是**輸給了後面的通用規則**:
 *   :553  .auth-main.v2.ipcs-auth-shell-stacked .auth-sidecontent { min-height: 0; padding: 0 }
 *   :921  .auth-main.v2.ipcs-auth-shell         .auth-sidecontent { min-height: 460px }   ← 贏
 *   :941  .auth-main.v2.ipcs-auth-shell         .auth-sidecontent { padding: 36px 24px }  ← 贏
 * 兩邊都是 4 個 class(0,4,0)特異度**完全相同**,所以純粹由 source order 決勝 ——
 * 而 stacked 那組寫在前面。登入頁的 class 同時含 ipcs-auth-shell 與 ipcs-auth-shell-stacked,
 * 於是品牌欄被硬撐成 460px + 72px padding:內容其實只有 78px 高的 LOGO,
 * 卻把表單卡推到 top:540 —— 在 640px 高的手機上表單直接掉出第一屏。
 *
 * 修法是**同時列出兩個 class 提高特異度(0,5,0)**,讓它不再依賴 source order。
 * 不用 !important:那只是把同樣的脆弱換個形式,下一個人照樣踩。 */
@media (max-width: 1199.98px) {
  .auth-main.v2.ipcs-auth-shell.ipcs-auth-shell-stacked .auth-sidecontent {
    min-height: 0;
    padding: 0;
  }
}

/* 手機可點目標放大(使用者 2026-08-08 要求全面確認 RWD 後補)。
 *
 * 實測(390x844)有三個真的太小:
 *   保持登入 checkbox   18x18
 *   忘記密碼連結        58x22
 *   超管頁的「這裡」連結 26x15   ← 最嚴重
 * (語言鈕 44x44、顯示密碼 56x52、Google 276x52 都合格,不動。)
 *
 * 手法是 **padding 撐開觸控範圍 + 等量負 margin 抵銷**,所以
 * 「摸得到的範圍變大,但看起來的位置一模一樣」—— 不會把版面推歪。
 * 只在手機生效:桌機用滑鼠沒有這個問題,放大反而讓連結的 hover 區域怪怪的。 */
@media (max-width: 767.98px) {
  .ipcs-tap-target,
  .auth-form a.ipcs-login-link {
    display: inline-block;
    padding: 11px 8px;
    margin: -11px -8px;
  }

  /* checkbox 本體放大到 22px,並讓它與文字的整條 row 都可點。 */
  .auth-form .form-check-input {
    width: 22px;
    height: 22px;
  }

  .auth-form .form-check-label {
    padding: 10px 0;
    margin: -10px 0;
  }

  /* 主要動作鈕補到 44px(Apple HIG 的建議下限),原本 41px。 */
  .auth-form [data-login-submit],
  .auth-form [data-sysadmin-form] button[type='submit'] {
    min-height: 44px;
  }
}

@media (max-width: 767.98px) {
  /* 手機:上下留白收斂,讓表單卡盡量待在第一屏 */
  .auth-main.v2.ipcs-auth-shell.ipcs-auth-shell-stacked .auth-wrapper {
    padding: 24px 16px;
    gap: 16px;
    justify-content: flex-start;
  }

  /* 卡片吃滿寬度 —— 原本 max-width:460px 在 390px 螢幕上還被 auth-form 的左右 padding
     再切掉一圈,實測只剩 278px,輸入框因此又窄一截。 */
  .auth-main.v2.ipcs-auth-shell.ipcs-auth-shell-stacked .auth-form {
    padding-left: 0;
    padding-right: 0;
  }
}

/* ── Credit/points pill on module cards ── */

.ipcs-credit-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 500;
  background: rgba(4, 169, 245, 0.08);
  color: #0c7bb8;
  border: 1px solid rgba(4, 169, 245, 0.18);
  margin-bottom: 8px;
}

.ipcs-credit-pill i {
  font-size: 1rem;
}

.ipcs-module-expiry-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 500;
  background: rgba(29, 233, 182, 0.1);
  color: #0a7a62;
  border: 1px solid rgba(29, 233, 182, 0.24);
  margin-bottom: 8px;
  margin-right: 6px;
}

.ipcs-module-expiry-pill i {
  font-size: 1rem;
}

.ipcs-credit-pill--empty {
  background: rgba(220, 53, 69, 0.08);
  color: #b52a37;
  border-color: rgba(220, 53, 69, 0.2);
}

.ipcs-credit-pill--unlimited {
  background: rgba(21, 128, 61, 0.08);
  color: #15803d;
  border-color: rgba(21, 128, 61, 0.18);
}

.ipcs-showcase-card,
.ipcs-module-card {
  border: 1px solid var(--bs-border-color);
  border-radius: 12px;
  background: var(--bs-card-bg);
  box-shadow: var(--pc-card-box-shadow);
}

.ipcs-showcase-card .card-body,
.ipcs-module-card .card-body {
  padding: 24px;
}

/* 取消外框 (使用者 2026-06-22:常用 + 工作入口去框,畫面更協調) — 去掉 border/陰影/底色與內距,內容齊頭對齊 */
.ipcs-showcase-card--bare {
  border: none;
  background: transparent;
  box-shadow: none;
}

.ipcs-showcase-card--bare > .card-body {
  padding: 0;
}

.ipcs-module-card {
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

/* H6 hover 治理:transform-lift 型 hover 包進 @media(hover:hover) — 觸控裝置 tap 後
   不再卡在浮起/反白狀態(手指離開才觸發、且沒有 mouseleave 收回),桌面滑鼠行為零改變。 */
@media (hover: hover) and (pointer: fine) {
  .ipcs-module-card:hover {
    transform: translateY(-2px);
    border-color: rgba(182, 146, 88, 0.34);
    box-shadow: 0 22px 52px rgba(25, 43, 63, 0.12);
  }
}

.ipcs-module-card .card-body {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.ipcs-module-card .d-flex.gap-2.mt-4 {
  margin-top: auto;
}

.ipcs-kpi {
  padding: 22px;
  border-radius: 18px;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
}

.ipcs-kpi strong {
  display: block;
  margin-top: 10px;
  font-size: 1.8rem;
  color: var(--bs-heading-color);
}

/* 2026-05-28:tone dots 改用 Bootstrap CSS 變數,跟模板 semantic color 同步 */

.ipcs-side-list {
  display: grid;
  gap: 14px;
}

.ipcs-side-list-item {
  padding: 16px;
  border: 1px solid #e5ebf0;
  border-radius: 16px;
  background: #fbfcfd;
}

.ipcs-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(182, 146, 88, 0.12);
  color: #8f6f3f;
  font-size: 0.8rem;
  font-weight: 600;
}

.ipcs-empty-state {
  padding: 28px;
  text-align: center;
  border-radius: 12px;
  border: 1px dashed #cfd8de;
  background: #fafcfd;
}

.ipcs-empty-state__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(4, 169, 245, 0.12);
  color: #04A9F5;
  font-size: 1.75rem;
}

.ipcs-summary-stack {
  display: grid;
  gap: 16px;
}

.ipcs-summary-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  color: #60707d;
}

.ipcs-summary-row strong {
  color: #293849;
}

.ipcs-module-symbol {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 12px;
  flex-shrink: 0;
  font-size: 1.5rem;
  line-height: 1;
  color: #1f3143;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.24);
  box-shadow: 0 14px 32px rgba(22, 33, 44, 0.08);
  transition: transform 0.18s ease;
  overflow: hidden;
}

.ipcs-module-symbol i {
  position: relative;
  z-index: 2;
}

@media (hover: hover) and (pointer: fine) {
  .ipcs-module-card:hover .ipcs-module-symbol {
    transform: translateY(-1px);
  }
}

.ipcs-module-symbol::before,
.ipcs-module-symbol::after {
  content: "";
  position: absolute;
  border-radius: inherit;
}

.ipcs-module-symbol::before {
  inset: 0;
  border: 1px solid rgba(170, 183, 194, 0.55);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.8),
    inset 0 -16px 24px rgba(255, 255, 255, 0.12);
}

.ipcs-module-symbol::after {
  inset: 9px;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.42);
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0)),
    repeating-linear-gradient(
      0deg,
      transparent 0,
      transparent 6px,
      rgba(31, 49, 67, 0.06) 6px,
      rgba(31, 49, 67, 0.06) 7px
    );
}

.ipcs-module-symbol-sky::before {
  background: linear-gradient(145deg, #eef3f7, #cad6df);
}

.ipcs-module-symbol-sky::after {
  background:
    linear-gradient(135deg, rgba(74, 115, 146, 0.16), rgba(255, 255, 255, 0.08)),
    linear-gradient(180deg, rgba(182, 146, 88, 0.06), transparent);
}

.ipcs-module-symbol-slate::before {
  background: linear-gradient(145deg, #eff2f4, #cfd5db);
}

.ipcs-module-symbol-slate::after {
  background:
    linear-gradient(135deg, rgba(73, 83, 96, 0.16), rgba(255, 255, 255, 0.08)),
    linear-gradient(180deg, rgba(182, 146, 88, 0.05), transparent);
}

.ipcs-module-symbol-amber::before {
  background: linear-gradient(145deg, #f4efe5, #d7ccb2);
}

.ipcs-module-symbol-amber::after {
  background:
    linear-gradient(135deg, rgba(182, 146, 88, 0.18), rgba(255, 255, 255, 0.08)),
    linear-gradient(180deg, rgba(182, 146, 88, 0.12), transparent);
}

.ipcs-module-symbol-emerald::before {
  background: linear-gradient(145deg, #edf3ef, #ccd9d2);
}

.ipcs-module-symbol-emerald::after {
  background:
    linear-gradient(135deg, rgba(51, 104, 88, 0.16), rgba(255, 255, 255, 0.08)),
    linear-gradient(180deg, rgba(182, 146, 88, 0.05), transparent);
}

.ipcs-module-symbol-copper::before {
  background: linear-gradient(145deg, #f4ede5, #dac4ad);
}

.ipcs-module-symbol-copper::after {
  background:
    linear-gradient(135deg, rgba(139, 94, 60, 0.2), rgba(255, 255, 255, 0.08)),
    linear-gradient(180deg, rgba(182, 146, 88, 0.12), transparent);
}

.ipcs-module-symbol-night::before {
  background: linear-gradient(145deg, #e5eaef, #bcc6d0);
}

.ipcs-module-symbol-night::after {
  background:
    linear-gradient(135deg, rgba(35, 53, 72, 0.24), rgba(255, 255, 255, 0.08)),
    linear-gradient(180deg, rgba(182, 146, 88, 0.06), transparent);
}

.ipcs-module-symbol-cyan::before {
  background: linear-gradient(145deg, #edf3f4, #cad7dc);
}

.ipcs-module-symbol-cyan::after {
  background:
    linear-gradient(135deg, rgba(74, 110, 120, 0.16), rgba(255, 255, 255, 0.08)),
    linear-gradient(180deg, rgba(182, 146, 88, 0.06), transparent);
}

.ipcs-module-card .badge {
  white-space: normal;
}

.ipcs-module-card p,
.ipcs-kpi,
.ipcs-side-list-item {
  word-break: break-word;
}

.ipcs-auth-shell .btn,
.ipcs-module-card .btn {
  border-radius: 8px;
}

@media (max-width: 1199.98px) {
  .auth-main.v2.ipcs-auth-shell .auth-wrapper,
.auth-main.v2.ipcs-auth-shell-wide .auth-wrapper {
    grid-template-columns: 1fr;
  }

  .auth-main.v2.ipcs-auth-shell .auth-sidecontent {
    min-height: 460px;
  }

  

  .auth-main.v2.ipcs-auth-shell-wide .auth-form,
  .auth-main.v2.ipcs-auth-shell .auth-form {
    padding: 28px 20px 40px;
  }
}

@media (max-width: 991.98px) {
  .ipcs-page-head {
    flex-direction: column;
    align-items: stretch;
    padding: 24px;
  }

  

  .auth-main.v2.ipcs-auth-shell .auth-sidecontent {
    padding: 36px 24px;
  }
}

@media (max-width: 767.98px) {
  .ipcs-topbar-pill {
    min-width: 0;
  }

  .auth-main.v2.ipcs-auth-shell .auth-form .card-body {
    padding: 24px;
  }
}

/* .ipcs-showcase-card / .ipcs-module-card / .ipcs-page-head / .ipcs-kpi 已改吃
   Light Able 變數 (--bs-card-bg / --bs-border-color / --pc-card-box-shadow),
   會自動跟著模板 light/dark,不再需要手刻深色 override (使用者 2026-06-12 跑色修正)。 */
body[data-pc-theme='dark'] .ipcs-sidebar-card,
body[data-pc-theme='dark'] .ipcs-side-list-item,
body[data-pc-theme='dark'] .ipcs-empty-state,
body[data-pc-theme='dark'] .ipcs-sidebar-user-card {
  border-color: #303f50;
  background:
    linear-gradient(180deg, rgba(26, 36, 48, 0.96), rgba(21, 30, 40, 0.98)),
    radial-gradient(circle at top right, rgba(182, 146, 88, 0.12), transparent 26%);
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.28);
}

body[data-pc-theme='dark'] .ipcs-topbar-pill {
  border-color: #303f50;
  background: rgba(20, 28, 38, 0.86);
}

body[data-pc-theme='dark'] .ipcs-sidebar-user-card__subtitle {
  color: #cbd5e1;
}

body[data-pc-theme='dark'] .ipcs-sidebar-upgrade-card {
  border-color: rgba(96, 204, 255, 0.38);
  background: linear-gradient(135deg, rgba(96, 204, 255, 0.14), rgba(96, 204, 255, 0.04));
  color: #d6ecfb;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.35);
}

body[data-pc-theme='dark'] .ipcs-sidebar-upgrade-card:hover,
body[data-pc-theme='dark'] .ipcs-sidebar-upgrade-card:focus {
  border-color: rgba(96, 204, 255, 0.68);
  color: #ffffff;
  box-shadow: 0 20px 44px rgba(0, 0, 0, 0.45);
}

body[data-pc-theme='dark'] .ipcs-sidebar-upgrade-card__icon {
  background: rgba(96, 204, 255, 0.18);
  color: #60ccff;
}

body[data-pc-theme='dark'] .ipcs-sidebar-upgrade-card__copy strong {
  color: #e6f3fc;
}

body[data-pc-theme='dark'] .ipcs-sidebar-upgrade-card__copy small {
  color: #b0c4d6;
}

body[data-pc-theme='dark'] .ipcs-sidebar-upgrade-card__chevron {
  color: #60ccff;
}

body[data-pc-theme='dark'] .ipcs-topbar-pill__copy strong {
  color: #edf3f7;
}

body[data-pc-theme='dark'] .ipcs-topbar-pill__copy small {
  color: #98a8b7;
}

body[data-pc-theme='dark'] .ipcs-page-head h2,
body[data-pc-theme='dark'] .ipcs-showcase-card h4,
body[data-pc-theme='dark'] .ipcs-module-card h5,
body[data-pc-theme='dark'] .ipcs-summary-row strong,
body[data-pc-theme='dark'] .ipcs-kpi strong,
body[data-pc-theme='dark'] .ipcs-profile-dropdown .dropdown-item,
body[data-pc-theme='dark'] .pc-user-card h6 {
  color: var(--bs-heading-color);
}

body[data-pc-theme='dark'] .ipcs-summary-row,
body[data-pc-theme='dark'] .pc-user-card small,
body[data-pc-theme='dark'] .ipcs-profile-dropdown .dropdown-item-text {
  color: #748892;
}

/* 對齊模板原生:[data-pc-theme=dark] .text-muted = #748892(對比 ~4.3:1,勉強過 AA)。 */
body[data-pc-theme='dark'] .text-muted {
  color: #748892 !important;
}

/* 模板的深色版 --bs-secondary-color 只寫在 [data-bs-theme=dark](Bootstrap 原生屬性),
   但 Light Able 是用 body[data-pc-theme=dark] 切深色 → 那條永遠不會生效,於是任何
   color:var(--bs-secondary-color) 的次要文字/breadcrumb/icon 在深色底都是「深字配深底」看不見。
   在 body 層級補上模板原生深色次要文字色 #748892,一次修好所有用到此變數的地方。 */
body[data-pc-theme='dark'] {
  --bs-secondary-color: #748892;
}

body[data-pc-theme='dark'] .ipcs-module-symbol {
  color: #f1f5f8;
  text-shadow: none;
}

body[data-pc-theme='dark'] .ipcs-module-symbol::before {
  border-color: rgba(120, 133, 149, 0.62);
}

body[data-pc-theme='dark'] .ipcs-module-symbol::after {
  border-color: rgba(255, 255, 255, 0.16);
}

body[data-pc-theme='dark'] .ipcs-profile-dropdown,
body[data-pc-theme='dark'] .pc-h-dropdown {
  background: #1f2a36;
  border-color: #303f50;
}

body[data-pc-theme='dark'] .dropdown-item:hover,
body[data-pc-theme='dark'] .dropdown-item:focus {
  background: rgba(255, 255, 255, 0.06);
}

.ipcs-auth-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.ipcs-auth-brand-block {
  margin: 0 auto;
  text-align: center;
  /* 白底改黑字版,黑字標在白底已有足夠對比,移除舊深色霧面底板 (使用者 2026-07-06) */
  width: fit-content;
  max-width: 460px;
  padding: 30px 44px;
}

.ipcs-login-form-shell .card {
  border-radius: 12px;
  border: 1px solid rgba(216, 224, 231, 0.92);
  box-shadow: 0px 8px 24px rgba(41, 52, 74, 0.1);
}

.ipcs-login-form-shell .card-body {
  padding: 40px;
}

.ipcs-form-label {
  margin-bottom: 10px;
  font-size: 0.85rem;
  font-weight: 600;
  color: #526273;
}

.ipcs-password-group .form-control,
.ipcs-password-group .btn {
  height: 52px;
}

.ipcs-password-group .btn {
  min-width: 56px;
}

.ipcs-password-toggle i {
  font-size: 1.15rem;
}

.ipcs-login-link {
  color: #1a73e8;
  font-size: 0.9rem;
  text-decoration: none;
}

.ipcs-login-register-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid #e5ebf0;
  /* 0.9rem → 1rem(2026-08-19 使用者反映太小)。這一行是「我走錯頁了」的唯一出口,
     不該比它上面的任何一句話小。 */
  font-size: 1rem;
}

.ipcs-login-register-link {
  border: 0;
  background: transparent;
  padding: 0;
  font-weight: 600;
  color: #1a73e8;
  cursor: pointer;
}

.ipcs-login-register-link:hover {
  text-decoration: underline;
}

/* ── 登入頁的「立即註冊」:上市階段的第二條主要動線 ──────────────────
   進到登入頁的人多數還沒有帳號,所以它不是頁尾註腳,而是一顆與登入鈕同尺寸的按鈕。
   顏色仍是 light-secondary —— 兩顆同為 primary 會讓已有帳號的人猶豫該按哪顆。 */
.ipcs-login-signup {
  margin-top: 16px;
  text-align: center;
}

.ipcs-login-signup__label {
  margin-bottom: 8px;
  font-size: 1rem;
}

.ipcs-login-signup__btn {
  height: 54px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  font-weight: 600;
}

.ipcs-social-login-stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ipcs-social-login-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

.ipcs-social-login {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  /* 52 → 54px、0.95 → 1rem(2026-08-19 使用者反映太小)。
     它與上方主要登入鈕是**並行的另一條路**,不是附註,尺寸就不該像附註。 */
  height: 54px;
  padding: 0 16px;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  transition: transform 0.18s ease, box-shadow 0.18s ease, filter 0.18s ease;
}

.ipcs-social-login:hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.12);
  filter: saturate(1.03);
}

.ipcs-social-login__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
}

.ipcs-social-login__icon svg {
  width: 22px;
  height: 22px;
  display: block;
}

/* ── Workspace Selector (compact, no-scroll) ── */

.auth-main.v2.ipcs-auth-shell-workspaces .auth-wrapper {
  grid-template-columns: 1fr;
}

.ipcs-auth-shell-workspaces .auth-form {
  align-items: center;
  justify-content: center;
  padding: 0;
  min-height: 100dvh;
}

.ipcs-ws-page {
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  padding: 40px 28px;
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.ipcs-ws-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
}

.ipcs-ws-header h4 {
  font-size: 1.15rem;
  color: #17283a;
}

.ipcs-ws-header p {
  font-size: 0.88rem;
  color: #475569;
}

.ipcs-ws-header .ipcs-brand-copy strong {
  color: #17283a;
}

.ipcs-ws-header .ipcs-brand-copy small {
  color: #475569;
}

.ipcs-ws-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}

/* 半原生:基底吃模板 card token(圓角/間距/邊框/底色),fallback 是 .card 外無法解析 var 時的保底值。
   情境配色漸層變體寫在後面,靠宣告順序覆蓋,不受影響(2026-06-23) */
.ipcs-ws-card {
  display: flex;
  flex-direction: column;
  padding: var(--bs-card-spacer-y, 25px) var(--bs-card-spacer-x, 25px);
  border-radius: var(--bs-card-border-radius, 12px);
  border: var(--bs-card-border-width, 1px) solid var(--bs-card-border-color, #d8e0e7);
  background: var(--bs-card-bg, #fff);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s;
  position: relative;
  overflow: hidden;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card:hover {
    border-color: rgba(182, 146, 88, 0.5);
    box-shadow: 0 12px 36px rgba(25, 43, 63, 0.1);
    transform: translateY(-2px);
    text-decoration: none;
    color: inherit;
  }
}

.ipcs-ws-card.is-current {
  border-color: rgba(182, 146, 88, 0.48);
  box-shadow: 0 8px 28px rgba(25, 43, 63, 0.1);
}

.ipcs-ws-card::after {
  content: "";
  position: absolute;
  inset: auto -30px -40px auto;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(182, 146, 88, 0.1), transparent 72%);
  pointer-events: none;
}

/* ── Workspace card logo ── */
.ipcs-ws-card__logo {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  object-fit: cover;
  border: 2px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}

/* ── Workspace card solid color variants ── */
/* 個人擁有者 (warning 橘) */
.ipcs-ws-card--warning {
  background: linear-gradient(135deg, #b45309, #d97706);
  border-color: transparent;
  color: #fff;
}
.ipcs-ws-card--warning::after { background: radial-gradient(circle, rgba(255,255,255,0.08), transparent 72%); }
.ipcs-ws-card--warning .ipcs-ws-card__name strong { color: #fff; }
.ipcs-ws-card--warning .ipcs-ws-card__type { background: rgba(255,255,255,0.2); color: #fff; }
.ipcs-ws-card--warning .ipcs-ws-card__desc { color: rgba(255,255,255,0.8); }
.ipcs-ws-card--warning .ipcs-ws-card__status { color: rgba(255,255,255,0.7); }
.ipcs-ws-card--warning .ipcs-ws-card__enter { color: #fff; }
.ipcs-ws-card--warning .ipcs-ws-card__footer { border-top-color: rgba(255,255,255,0.15); }
.ipcs-ws-card--warning .badge { background: rgba(255,255,255,0.2) !important; color: #fff !important; border-color: rgba(255,255,255,0.3) !important; }

@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--warning:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(180, 83, 9, 0.35); }
}
.ipcs-ws-card--warning.is-current { box-shadow: 0 12px 36px rgba(180, 83, 9, 0.3); }

/* 超級管理者 (primary 藍) */
.ipcs-ws-card--primary {
  background: linear-gradient(135deg, #1e3a8a, #3b82f6);
  border-color: transparent;
  color: #fff;
}
.ipcs-ws-card--primary::after { background: radial-gradient(circle, rgba(255,255,255,0.06), transparent 72%); }
.ipcs-ws-card--primary .ipcs-ws-card__name strong { color: #fff; }
.ipcs-ws-card--primary .ipcs-ws-card__type { background: rgba(255,255,255,0.2); color: #fff; }
.ipcs-ws-card--primary .ipcs-ws-card__desc { color: rgba(255,255,255,0.8); }
.ipcs-ws-card--primary .ipcs-ws-card__status { color: rgba(255,255,255,0.7); }
.ipcs-ws-card--primary .ipcs-ws-card__enter { color: #fff; }
.ipcs-ws-card--primary .ipcs-ws-card__footer { border-top-color: rgba(255,255,255,0.15); }
.ipcs-ws-card--primary .badge { background: rgba(255,255,255,0.2) !important; color: #fff !important; border-color: rgba(255,255,255,0.3) !important; }

@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--primary:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(30, 58, 138, 0.4); }
}
.ipcs-ws-card--primary.is-current { box-shadow: 0 12px 36px rgba(30, 58, 138, 0.35); }

/* 協作成員 (success 綠) */
.ipcs-ws-card--success {
  background: linear-gradient(135deg, #065f46, #10b981);
  border-color: transparent;
  color: #fff;
}
.ipcs-ws-card--success::after { background: radial-gradient(circle, rgba(255,255,255,0.06), transparent 72%); }
.ipcs-ws-card--success .ipcs-ws-card__name strong { color: #fff; }
.ipcs-ws-card--success .ipcs-ws-card__type { background: rgba(255,255,255,0.2); color: #fff; }
.ipcs-ws-card--success .ipcs-ws-card__desc { color: rgba(255,255,255,0.8); }
.ipcs-ws-card--success .ipcs-ws-card__status { color: rgba(255,255,255,0.7); }
.ipcs-ws-card--success .ipcs-ws-card__enter { color: #fff; }
.ipcs-ws-card--success .ipcs-ws-card__footer { border-top-color: rgba(255,255,255,0.15); }
.ipcs-ws-card--success .badge { background: rgba(255,255,255,0.2) !important; color: #fff !important; border-color: rgba(255,255,255,0.3) !important; }

@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--success:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(6, 95, 70, 0.4); }
}
.ipcs-ws-card--success.is-current { box-shadow: 0 12px 36px rgba(6, 95, 70, 0.35); }

/* 專案管理者 (danger 紅) */
.ipcs-ws-card--danger {
  background: linear-gradient(135deg, #991b1b, #ef4444);
  border-color: transparent;
  color: #fff;
}
.ipcs-ws-card--danger::after { background: radial-gradient(circle, rgba(255,255,255,0.06), transparent 72%); }
.ipcs-ws-card--danger .ipcs-ws-card__name strong { color: #fff; }
.ipcs-ws-card--danger .ipcs-ws-card__type { background: rgba(255,255,255,0.2); color: #fff; }
.ipcs-ws-card--danger .ipcs-ws-card__desc { color: rgba(255,255,255,0.8); }
.ipcs-ws-card--danger .ipcs-ws-card__status { color: rgba(255,255,255,0.7); }
.ipcs-ws-card--danger .ipcs-ws-card__enter { color: #fff; }
.ipcs-ws-card--danger .ipcs-ws-card__footer { border-top-color: rgba(255,255,255,0.15); }
.ipcs-ws-card--danger .badge { background: rgba(255,255,255,0.2) !important; color: #fff !important; border-color: rgba(255,255,255,0.3) !important; }

@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--danger:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(153, 27, 27, 0.4); }
}
.ipcs-ws-card--danger.is-current { box-shadow: 0 12px 36px rgba(153, 27, 27, 0.35); }

/* 瀏覽成員 (info 青) */
.ipcs-ws-card--info {
  background: linear-gradient(135deg, #155e75, #06b6d4);
  border-color: transparent;
  color: #fff;
}
.ipcs-ws-card--info::after { background: radial-gradient(circle, rgba(255,255,255,0.06), transparent 72%); }
.ipcs-ws-card--info .ipcs-ws-card__name strong { color: #fff; }
.ipcs-ws-card--info .ipcs-ws-card__type { background: rgba(255,255,255,0.2); color: #fff; }
.ipcs-ws-card--info .ipcs-ws-card__desc { color: rgba(255,255,255,0.8); }
.ipcs-ws-card--info .ipcs-ws-card__status { color: rgba(255,255,255,0.7); }
.ipcs-ws-card--info .ipcs-ws-card__enter { color: #fff; }
.ipcs-ws-card--info .ipcs-ws-card__footer { border-top-color: rgba(255,255,255,0.15); }
.ipcs-ws-card--info .badge { background: rgba(255,255,255,0.2) !important; color: #fff !important; border-color: rgba(255,255,255,0.3) !important; }

@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--info:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(21, 94, 117, 0.4); }
}
.ipcs-ws-card--info.is-current { box-shadow: 0 12px 36px rgba(21, 94, 117, 0.35); }

.ipcs-ws-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.ipcs-ws-card__top .ipcs-avatar {
  font-size: 1.6rem;
}

/* 展示模式：在工作區卡片右上角標出測試身份，例如 (個人版・已訂閱) */
.ipcs-ws-card__showcase-tag {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 3px 8px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.32);
  white-space: nowrap;
}
.ipcs-ws-card--warning .ipcs-ws-card__showcase-tag,
.ipcs-ws-card--primary .ipcs-ws-card__showcase-tag,
.ipcs-ws-card--success .ipcs-ws-card__showcase-tag,
.ipcs-ws-card--danger .ipcs-ws-card__showcase-tag,
.ipcs-ws-card--info .ipcs-ws-card__showcase-tag {
  background: rgba(255, 255, 255, 0.22);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.38);
}

.ipcs-ws-card__body {
  flex: 1;
}

.ipcs-ws-card__name {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.ipcs-ws-card__name strong {
  font-size: 1.05rem;
  color: #233548;
}

.ipcs-ws-card__type {
  font-size: 0.76rem;
  color: #39465F;
  background: #e8eef3;
  padding: 1px 7px;
  border-radius: 4px;
}

.ipcs-ws-card__desc {
  margin: 8px 0 0;
  font-size: 0.84rem;
  color: #4a5c6b;
  line-height: 1.5;
}

.ipcs-ws-card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid #edf2f7;
}

.ipcs-ws-card__status {
  font-size: 0.8rem;
  color: #5a6b7a;
}

.ipcs-ws-card__enter {
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ipcs-button, #1b6ca8);
  display: flex;
  align-items: center;
  gap: 4px;
  transition: gap 0.18s;
}

@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card:hover .ipcs-ws-card__enter {
    gap: 8px;
  }
}

/* ── 公司卡「圖片置中」版面(2026-10-02 使用者,WorkspaceCard 的 `media`)──────────────
   使用者:有設定圖片的公司,圖片放大置中、**不要任何底色**(透明 logo 會跟色塊混在一起),
   卡片底色跟著使用者自己的深淺色設定;沒有圖片的公司也要排得整齊。
   ⇒ 卡片用主題的卡片底色(`.ipcs-ws-card` 基底,深色模式在下方 dark 區已處理),不用彩色漸層;
      上半部是固定高度的展示區,有圖放圖、沒圖放字首頭像 —— 有圖沒圖的卡片一樣高。 */
.ipcs-ws-card__tag-row {
  display: flex;
  justify-content: flex-end;
  min-height: 22px;              /* 沒有標籤的卡片也留同樣的高度,展示區才對得齊 */
}

.ipcs-ws-card__media {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 96px;
  margin: 4px 0 16px;
}

.ipcs-ws-card__media-img {
  display: block;
  max-width: 100%;
  max-height: 96px;
  object-fit: contain;           /* 不裁切:AUTH 的圖不保證是正方形(見 .ipcs-ws-avatar__img 的註解) */
  background: transparent;       /* 刻意不墊底色 */
}

.ipcs-ws-card__media-avatar {
  width: 72px;
  height: 72px;
  font-size: 1.8rem;
}

.ipcs-ws-card__body--center .ipcs-ws-card__name {
  justify-content: center;
  text-align: center;
}

.ipcs-ws-card--plain .ipcs-ws-card__enter-icon {
  color: var(--bs-primary);
}

.ipcs-ws-card--plain.is-current,
body[data-pc-theme='dark'] .ipcs-ws-card--plain.is-current {
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 1px var(--bs-primary);
}

/* 建立工作區 CTA 卡片 */
.ipcs-ws-card--create {
  border: 2px dashed #b0bec5;
  background: transparent;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 200px;
}
@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--create:hover {
    border-color: #04A9F5;
    background: rgba(4, 169, 245, 0.04);
    box-shadow: 0 12px 36px rgba(4, 169, 245, 0.12);
  }
}
.ipcs-ws-card__create-icon {
  font-size: 2.5rem;
  color: #b0bec5;
  margin-bottom: 8px;
  transition: color 0.18s;
}
@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--create:hover .ipcs-ws-card__create-icon {
    color: #04A9F5;
  }
}
.ipcs-ws-card--create .ipcs-ws-card__name strong {
  color: #39465F;
  font-size: 1rem;
}
.ipcs-ws-card--create .ipcs-ws-card__desc {
  color: #8a9bae;
  font-size: 0.82rem;
}
.ipcs-ws-card--create .ipcs-ws-card__footer {
  border-top: none;
}
.ipcs-ws-card--create .ipcs-ws-card__enter {
  color: #04A9F5;
  font-weight: 600;
}

.ipcs-topbar-bar {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 16px;
  width: 100%;
}

.ipcs-topbar-bar__left,
.ipcs-topbar-bar__right {
  display: flex;
  align-items: center;
}

.ipcs-topbar-bar__right {
  justify-content: flex-end;
}

.ipcs-topbar-bar__center {
  display: flex;
  justify-content: center;
}

.ipcs-topbar-current-workspace {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-width: min(520px, 100%);
  max-width: 100%;
  padding: 0 18px;
  border-radius: 999px;
  background: transparent;
}

.ipcs-topbar-current-workspace > i {
  font-size: 1.1rem;
  color: #48617b;
}

.ipcs-topbar-pill__copy {
  align-items: center;
  text-align: center;
}

.ipcs-topbar-current-workspace .ipcs-topbar-pill__copy small {
  font-size: 0.74rem;
  letter-spacing: 0.08em;
}

.ipcs-topbar-current-workspace .ipcs-topbar-pill__copy strong {
  font-size: 1.24rem;
  line-height: 1.1;
}

.ipcs-topbar-credit-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 12px;
  border-radius: 8px;
  font-size: 0.78rem;
  font-weight: 500;
  background: rgba(4, 169, 245, 0.08);
  color: #0c7bb8;
  border: 1px solid rgba(4, 169, 245, 0.15);
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.15s;
}

.ipcs-topbar-credit-pill:hover {
  background: rgba(4, 169, 245, 0.14);
  color: #0c7bb8;
  text-decoration: none;
}

.ipcs-topbar-credit-pill i {
  font-size: 0.92rem;
}

.ipcs-modules-page {
  display: grid;
  gap: 20px;
}

.ipcs-portal-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(300px, 0.95fr);
  gap: 24px;
}

/* 企業版隱藏右側欄時，主欄佔滿整列 */
.ipcs-portal-grid--single {
  grid-template-columns: 1fr;
}

.ipcs-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.ipcs-product-page {
  display: grid;
  gap: 24px;
}

.ipcs-product-helper {
  font-size: 0.92rem;
  line-height: 1.55;
  color: #4a5c6b;
}

body[data-pc-theme='dark'] .ipcs-product-helper {
  color: #748892;
}

.ipcs-product-head,
.ipcs-product-head__identity {
  display: flex;
  align-items: flex-start;
  gap: 18px;
}

.ipcs-product-head {
  justify-content: space-between;
}

.ipcs-product-facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-top: 24px;
}

/* 說明小 icon — 放在頁面標題旁,hover 用 tooltip 顯示該頁詳細功能 */
.ipcs-help-hint {
  color: var(--bs-secondary-color);
  font-size: 1.05rem;
  line-height: 1;
  cursor: help;
  opacity: 0.7;
  transition: opacity 0.15s ease, color 0.15s ease;
}
.ipcs-help-hint:hover,
.ipcs-help-hint:focus {
  opacity: 1;
  color: var(--bs-primary);
}

/* 深色模式:模板沒幫 --bs-secondary-color 換深色值,沿用會是深字壓深底 → icon 看不見。
   標題旁的說明 icon 對齊模板原生次要文字色 #748892。 */
body[data-pc-theme='dark'] .ipcs-help-hint {
  color: #748892;
}

.ipcs-product-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(320px, 0.9fr);
  gap: 24px;
}

.ipcs-quick-step-list {
  display: grid;
  gap: 14px;
}

.ipcs-quick-step {
  padding: 18px;
  border: 1px solid #e5ebf0;
  border-radius: 18px;
  background: #fbfcfd;
}

/* ── Configurator layout ── */

/* ── Module config cards ── */

/* ── Sub-feature items ── */

/* ── Credits options ── */

/* ── Order detail (Step 2) ── */

/* Dark mode selected card */

/* ═══════ Catalog page (產品方案) ═══════ */

/* 獨立模組 grid */

/* 價格列表 */

/* 套裝版 grid */

/* 套裝版 — 包含模組標籤 */

/* 套裝版 — 對照表 */

.ipcs-modules-page__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.ipcs-modules-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 24px;
}

.ipcs-modules-toolbar__search {
  flex: 1 1 320px;
  min-width: 240px;
}

.ipcs-modules-toolbar__filters,
.ipcs-modules-toolbar__view {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.ipcs-modules-search {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 0 14px;
  border: 1px solid #d8e0e7;
  border-radius: 16px;
  background: #fff;
  color: #39465F;
}

.ipcs-modules-search i {
  font-size: 1rem;
  color: #39465F;
}

.ipcs-modules-search input {
  width: 100%;
  border: 0;
  background: transparent;
  color: #1f2937;
  font-size: 0.92rem;
}

.ipcs-modules-search input:focus {
  outline: none;
}

.ipcs-portal-switcher {
  max-width: 360px;
}

.ipcs-portal-panel {
  display: block;
}

/* FOUC 防閃:工作入口分頁(專案/產品)在第一幀就依使用者上次選的模式顯示。
   <html data-ipcs-portal-mode> 由 Apps 頁頂同步小 script 在面板畫出來前設好,
   這幾條比 [hidden] / 元素預設 display 特異度高 → 不必 !important 即可決定首幀顯示哪面板。
   無紀錄時不設屬性 → 不命中這些規則 → 沿用伺服器 hidden 預設 (使用者 2026-06-25)。 */
html[data-ipcs-portal-mode='project'] [data-ipcs-portal-panel='module'],
html[data-ipcs-portal-mode='module'] [data-ipcs-portal-panel='project'] {
  display: none;
}

html[data-ipcs-portal-mode='project'] [data-ipcs-portal-panel='project'],
html[data-ipcs-portal-mode='module'] [data-ipcs-portal-panel='module'] {
  display: block;
}

.ipcs-module-collection {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

/* 工作入口「產品」分頁:自適應欄數的卡片牆。
   `align-items: start` 保留原本用 flex 的唯一理由 —— **不等高** → 單入口系統卡自然變矮,
   不會被同列最高的卡撐出空洞(使用者 2026-06-25)。

   2026-07-28 改成 grid:原本是 `flex: 0 1 320px`(固定寬、不許長大),1440px 下容器 1080px
   只排得下 3 張 320px 的卡,右側固定空著 84px,第 4 個產品孤零零掉到第二列 —— 使用者回報
   「四個產品沒有長滿寬度」。改成 auto-fill 之後欄寬會自己補滿整列(1080 → 3 欄各 348px),
   視窗變窄自動降成 2 欄、1 欄,不必寫任何斷點。
   用 auto-fill 而非 auto-fit 是刻意的:只有一個產品時 auto-fit 會把那張卡拉成整列寬,
   auto-fill 則讓它維持正常卡寬。 */
.ipcs-module-collection--portal {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  align-items: start;
}

/* grid 子項預設 min-width:auto → 內容(尤其編輯群組時的工具列)能把卡撐爆,必須明確歸零 */
.ipcs-module-collection--portal .ipcs-module-card-clean {
  min-width: 0;
}

/* 產品分頁的系統卡:識別區只有 icon + 系統名 + 描述(無徽章列),icon 與名稱垂直置中。
   只 scope 在 --portal,避免影響 Modules/Portal 那種「徽章列在上、內容較高」的卡(置中會讓 icon 飄中間)。
   使用者 2026-06-25。 */
.ipcs-module-collection--portal .ipcs-module-card-clean__identity {
  align-items: center;
}

/* 產品分頁單入口系統:把唯一的「進入」磚(.ipcs-pp-tile--enter)拉成填滿卡寬的橫向大鈕,
   讓單入口卡不再只有角落一顆小磚,視覺份量跟塞滿磚的多功能卡對等。
   只 scope 在 --portal,不影響專案分頁的方磚。使用者 2026-06-25。 */
.ipcs-module-collection--portal .ipcs-pp-tile--enter {
  grid-column: 1 / -1;
  width: 100%;
  height: 62px;
  aspect-ratio: auto;
  flex-direction: row;
  gap: 8px;
}

.ipcs-module-collection--portal .ipcs-pp-tile--enter .ipcs-pp-tile__name {
  width: auto;
  font-size: 0.95rem;
}

/* 產品分頁:系統卡內的功能磚改成 3 欄等分 grid → 磚長大填滿整個卡寬,
   消掉右側那塊用不到的留白(使用者 2026-06-26)。維持正方比例。
   只 scope 在 --portal,不動專案分頁/產品中心的 70px 方磚。 */
/* __actions 是 flex,.ipcs-pp-card 預設 flex:0 1 auto 會縮成內容寬 → 撐滿整列才填得滿卡寬 */
.ipcs-module-collection--portal .ipcs-pp-card {
  flex: 1 1 100%;
}
.ipcs-module-collection--portal .ipcs-pp-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.ipcs-module-collection--portal .ipcs-pp-tiles .ipcs-pp-tile:not(.ipcs-pp-tile--enter) {
  width: auto;
  height: auto;
  aspect-ratio: 1 / 1;
}

.ipcs-module-card-clean .card-body {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.ipcs-module-card-clean__main {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.ipcs-module-card-clean__identity {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.ipcs-module-card-clean__meta {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ipcs-module-card-clean__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.ipcs-module-card-clean__actions .btn {
  min-width: 110px;
}

/* 產品中心的功能磚:填滿卡片寬度,不要在右側留一條用不到的空白。
   原本是 `.ipcs-pp-tiles` 的 flex-wrap + 固定 70px 方磚 —— 卡片內可用寬 281px,
   一列排 3 顆(70×3 + 7×2 = 224)之後**右邊固定空 57px**(2026-07-29 使用者回報、實機量到)。
   工作入口的產品分頁早就改成等分格線了(:1893),這裡沿用同一個做法。
   用 auto-fill 而不是寫死 3 欄:窄卡自動降成 2 欄,不必為每個斷點各寫一條。 */
.ipcs-module-collection:not(.ipcs-module-collection--portal) .ipcs-pp-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
  gap: 8px;
}
.ipcs-module-collection:not(.ipcs-module-collection--portal) .ipcs-pp-tiles .ipcs-pp-tile {
  width: auto;
  height: auto;
  aspect-ratio: 1 / 1;
}

.ipcs-module-collection.is-list-view {
  grid-template-columns: 1fr;
}

.ipcs-module-collection.is-list-view .ipcs-module-card-clean .card-body {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.ipcs-module-collection.is-list-view .ipcs-module-card-clean__main {
  flex: 1 1 auto;
}

.ipcs-module-collection.is-list-view .ipcs-module-card-clean__actions {
  justify-content: flex-end;
  min-width: 280px;
}

.ipcs-backoffice-project-list {
  display: grid;
  gap: 16px;
}

.ipcs-backoffice-project-card {
  padding: 20px;
  border: 1px solid #e5ebf0;
  border-radius: 12px;
  background: #fbfcfd;
}

/* 專案資訊欄:不再 flex-fill 撐滿,限制最大寬度讓功能鈕靠左 (使用者 2026-06-22)。
   改 flex column + gap 統一列距,各列移除 mb-2;justify-content:center 配合外層
   align-items-center → 內容真正垂直置中、無多餘下緣 (使用者 2026-06-25) */
/* info 改 flex:0 1 auto (使用者 2026-06-25):只取內容寬、不再 grow 撐出與產品卡間的空白,
   產品卡因此貼齊資訊欄;多出的空白收到右側 (成員鈕 ms-auto 那端)。長描述以 max-width 強制換行。 */
.ipcs-project-card__info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  flex: 0 1 auto;
  min-width: 200px;
  max-width: 460px;
}

.ipcs-sidebar-toggle {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.ipcs-sidebar-mode-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid #d8e0e7;
  border-radius: 8px;
  background: #f6f9fc;
  color: #516273;
  font-size: 0.84rem;
  font-weight: 700;
  transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}

.ipcs-sidebar-mode-button i {
  font-size: 1rem;
}

/* 工作入口切換:active tab 一律吃 preset 主色 (--ipcs-accent),換配色就跟著變;
   專案/模組兩 tab 同主色,靠 active 有底色 vs 未選灰底區分 (對齊 light-able nav-pills,使用者 2026-06-29 取消寫死綠色) */
.ipcs-sidebar-mode-button.is-active {
  border-color: var(--ipcs-accent-border);
  background: var(--ipcs-accent-soft);
  color: var(--ipcs-accent);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06);
}

/* 專案名稱:比原本 (h5) 大一級,更醒目 (使用者 2026-06-24)。
   word-break (使用者 2026-06-25):超長專案名 (連續無空白) 在 info 欄內換行,不橫向爆版。 */
.ipcs-project-card__title {
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1.3;
  word-break: break-word;
  overflow-wrap: anywhere;
}

/* ── 專案卡內「產品分組」(使用者 2026-06-24) ──
   排在專案資訊與「查看成員」之間 → 當 header flex 列的中間欄。
   產品有入口 URL → 整卡可點「進入」;無 → 卡內把功能 chip 攤開 (功能多時收進「更多功能」)。
   flex-wrap + 每卡 max-width (使用者 2026-06-25):每張產品卡有上限寬,不再撐滿整欄;
   單一產品 → 卡片固定寬靠左不被拉長;2~3 個產品 → 並排,放不下自動換行,不擠壓。 */
.ipcs-pp-grid {
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* 產品卡:每個系統一張有邊框的小卡,標題在上、正方形功能磚在下 (使用者 2026-06-25) */
.ipcs-pp-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 9px;
  flex: 0 1 auto;
  margin: 0;
  padding: 12px 14px;
  text-align: left;
  border: 1px solid #e5ebf0;
  border-radius: 12px;
  background: #fcfdfe;
  color: inherit;
  font: inherit;
}

.ipcs-pp-card__name {
  font-weight: 700;
  font-size: 0.82rem;
  color: #233548;
  line-height: 1.3;
  word-break: break-word;
}

.ipcs-pp-card__hint {
  font-size: 0.78rem;
  color: #94a3b8;
}

/* 一排排列,放不下自動換行 (一個系統的功能磚) */
.ipcs-pp-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

/* 正方形功能磚:icon 在上、名稱在下,直接點擊另開 (使用者 2026-06-25)。
   高度用 min-height:名稱長(如「建築管理BIM」)會換行撐高,同列磚以最高者對齊 (使用者 2026-06-29)。 */
.ipcs-pp-tile {
  position: relative;
  width: 70px;
  min-height: 70px;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 5px;
  border-radius: 10px;
  border: 1px solid var(--ipcs-accent-border);
  background: var(--ipcs-accent-soft);
  color: var(--ipcs-accent);
  cursor: pointer;
  text-align: center;
  line-height: 1.15;
  transition: transform 0.16s ease, background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
}

.ipcs-pp-tile > i {
  font-size: 1.4rem;
}

.ipcs-pp-tile__name {
  width: 100%;
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.2;
  word-break: break-word;
}

/* H6 hover 治理:同上,:hover 與 :focus-visible 拆開,只把 :hover 包進 @media(hover:hover)。 */
@media (hover: hover) and (pointer: fine) {
  .ipcs-pp-tile:hover {
    background: var(--ipcs-accent);
    color: #fff;
    transform: translateY(-2px);
    box-shadow: 0px 8px 24px rgba(27, 46, 94, 0.12);
    outline: none;
  }
}
.ipcs-pp-tile:focus-visible {
  background: var(--ipcs-accent);
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0px 8px 24px rgba(27, 46, 94, 0.12);
  outline: none;
}

/* 超出可見上限 (>3 時前 2 顆以外) 的功能磚:JS 未跑前先隱藏,reorderPpCard 會把它們搬進浮出選單。 */
.ipcs-pp-tile--overflow {
  display: none;
}

/* 「更多功能」浮出選單 (使用者 2026-06-29):
   絕對定位不撐版面/不跑版,以小箭頭與按鈕相連,只放沒露出的功能磚,不重複系統名稱。 */
.ipcs-pp-more {
  position: relative;
  display: inline-flex;
}
.ipcs-pp-more__menu {
  position: absolute;
  top: calc(100% + 9px);
  left: 0;
  z-index: 30;
  width: max-content;
  max-width: min(254px, 90vw); /* 三欄 tiles(224,捲動時+6) + 左右 padding(20) + border(2) → 不留多餘白框;功能少時自動縮窄 */
  padding: 10px;
  border: 1px solid #e5ebf0;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0px 8px 24px rgba(27, 46, 94, 0.16);
}
/* 與按鈕相連的小箭頭 (放在 menu 上、捲軸在內層 tiles → 箭頭不會被裁掉)。水平位置由 JS 算(指向按鈕中間) */
.ipcs-pp-more__menu::before {
  content: "";
  position: absolute;
  top: -6px;
  left: var(--ipcs-pp-more-arrow, 24px);
  width: 11px;
  height: 11px;
  background: #fff;
  border-left: 1px solid #e5ebf0;
  border-top: 1px solid #e5ebf0;
  transform: rotate(45deg);
}
/* 往上彈 (下方空間不夠時,JS 加 --up):選單在按鈕上方,箭頭翻到底邊朝下 */
.ipcs-pp-more__menu--up {
  top: auto;
  bottom: calc(100% + 9px);
}
.ipcs-pp-more__menu--up::before {
  top: auto;
  bottom: -6px;
  border-left: 0;
  border-top: 0;
  border-right: 1px solid #e5ebf0;
  border-bottom: 1px solid #e5ebf0;
}
/* 水平位置(靠左 / 靠右 / 夾在視窗內)由 JS 算好直接設 left(PpCard.tsx、moreMenu.ts computeMoreMenuLeft)。
   原本手機一律靠右對齊,按鈕換行到左邊時選單跑出畫面左邊被切掉(使用者 2026-10-12)。 */
.ipcs-pp-more__tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  width: max-content;
  max-width: calc(70px * 3 + 7px * 2 + 1px); /* 三欄 (3 磚 70px + 2 間距 7px = 224px) + 1px 防 flex 邊界把第三顆擠下行;幾乎不留右側空白、左右對稱 */
  max-height: min(60vh, 340px); /* 一般功能數 (≤12,選單最多 4 列) 都放得下不捲動;太多才捲 (JS 會再依可視空間夾緊) */
  overflow-y: auto;
  scrollbar-gutter: auto; /* 不預留 gutter (預設值,明寫避免覆蓋舊版 stable),平常右側不多一條空白 */
}
/* 真的需要捲動時 (JS 加 is-scroll) 才補回 6px 捲軸寬,維持三欄;平常不留 gutter → 左右留白對稱 */
.ipcs-pp-more__tiles.is-scroll {
  max-width: calc(70px * 3 + 7px * 2 + 7px);
}
.ipcs-pp-more__tiles::-webkit-scrollbar {
  width: 6px;
}
.ipcs-pp-more__tiles::-webkit-scrollbar-thumb {
  background: rgba(120, 140, 160, 0.4);
  border-radius: 3px;
}
body[data-pc-theme='dark'] .ipcs-pp-more__menu {
  background: #1f2832;
  border-color: #303f50;
  box-shadow: 0px 10px 28px rgba(0, 0, 0, 0.45);
}
body[data-pc-theme='dark'] .ipcs-pp-more__menu::before {
  background: #1f2832;
  border-color: #303f50;
}

/* 自訂功能群組 — 編輯模式(Task 5)。
   每顆磚右上角的「⋮」→「移出群組 / 移到 X」:選單本身沿用模板 .dropdown-menu/.dropdown-item
   (style.css),這裡只補「小磚右上角 kebab」這個模板沒有的錨點與定位,不重造圓角/陰影/字級。 */
.ipcs-pp-tile-wrap {
  position: relative;
  display: inline-flex;
}
.ipcs-pp-tile-menu__toggle {
  position: absolute;
  top: -6px;
  right: -6px;
  z-index: 5;
  width: 20px;
  height: 20px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--ipcs-accent-border);
  background: #fff;
  color: var(--ipcs-accent);
  font-size: 0.72rem;
  line-height: 1;
  cursor: pointer;
}
body[data-pc-theme='dark'] .ipcs-pp-tile-menu__toggle {
  background: #1f2832;
  border-color: #303f50;
}
.ipcs-pp-tile-menu__list {
  top: 20px;
  right: -6px;
  left: auto;
  min-width: 160px;
  z-index: 30;
}

/* 系統卡右上角「編輯群組」切換鈕(ModulePanel):與 .ipcs-pin-btn.is-pinned 同一組 token,
   啟用時吃 accent 色,不另外發明新視覺。 */
.ipcs-group-edit-btn.is-editing {
  border-color: var(--ipcs-accent-border);
  background: var(--ipcs-accent-soft);
  color: var(--ipcs-accent);
}

/* 群組列的工具列(改名/刪除/上移/下移),編輯模式才出現;純 Bootstrap utility 排版,
   這個 class 只當測試/樣式錨點,不掛任何新視覺 token。 */
.ipcs-group-toolbar {
  border-bottom: 1px solid #e5ebf0; /* 沿用本檔既有分隔線灰(:2159),不再發明第三種相近灰 */
}
body[data-pc-theme='dark'] .ipcs-group-toolbar {
  border-bottom-color: #303f50;
}

/* ── 功能群組操作改版(2026-07-28)──
   使用者回報「編輯群組要建立群組那些功能有點不直覺」。對照 Chrome 分頁群組 / Slack 側邊欄 /
   Gmail 之後改成:群組由項目生出來、可多選批次搬、標題就地改名、可拖曳。
   以下全部沿用本檔既有 token(--ipcs-accent 系列、卡片圓角、既有分隔線灰),不發明新視覺。 */

/* 工具列改成貼在群組標題列右側(不再是獨立一列),所以拿掉底線、只留間距錨點 */
.ipcs-group-head .ipcs-group-toolbar {
  border-bottom: 0;
  flex: 0 0 auto;
}
body[data-pc-theme='dark'] .ipcs-group-head .ipcs-group-toolbar {
  border-bottom-color: transparent;
}

/* 標題就地改名的輸入框:塞在 .accordion-header 內,高度對齊 accordion-button 的內距 */
.ipcs-group-name-input {
  margin: 8px 12px;
  max-width: 320px;
}

/* 多選批次操作列:有選才出現。用 accent-soft 底色與虛線框,與「編輯中」的語意一致 */
.ipcs-group-bulkbar {
  padding: 10px 14px;
  border: 1px dashed var(--ipcs-accent-border);
  border-radius: var(--bs-card-border-radius, 12px);
  background: var(--ipcs-accent-soft);
}

/* 拖曳放置區:平常完全無感(透明外框先佔位,避免懸停時版面跳動),懸停才亮 */
.ipcs-group-dropzone {
  border: 1px dashed transparent;
  border-radius: var(--bs-card-border-radius, 12px);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.ipcs-group-dropzone.is-over {
  border-color: var(--ipcs-accent);
  background: var(--ipcs-accent-soft);
}

/* ── 編輯群組時磚變超大的根因(2026-07-28 使用者回報、實機量到)──
   `.ipcs-module-card-clean__actions .btn { min-width: 110px }`(本檔 :1928)本意是給卡片
   底部的「了解更多 / 購買」那種文字鈕統一寬度,但它是**後代選擇器** —— 群組工具列那 5 顆
   純圖示小鈕(收合/改名/上移/下移/刪除)整個被套上 110px:
     5 × 110 + 間距 = 574px,而且 min-width 不可壓縮
     → .ipcs-group-shell(flex 子項,預設 min-width:auto)被撐到 661px
     → 三欄磚格 .ipcs-pp-tiles 跟著 659px
     → 每格 214px,磚變 214×214 並溢出卡片右緣 365px
   沒有群組時工具列不存在,所以「沒群組正常、一有群組就爆掉」—— 正是使用者描述的現象。
   治病灶:群組 UI 內的按鈕不吃這個 110px。 */
.ipcs-module-card-clean__actions .ipcs-group-shell .btn {
  min-width: 0;
}

/* 安全帶:群組 UI 這條鏈上每一層都要能縮回卡寬。flex/grid 子項預設 min-width:auto
   (＝不得小於子孫的 min-content),只要有任何一個不可壓縮的子孫就能再次把卡片撐開。
   上面那條治的是這次的病灶,這條是不讓同樣的病再犯。 */
.ipcs-group-shell,
.ipcs-group-shell .accordion-item,
.ipcs-group-shell .accordion-header,
.ipcs-group-shell .accordion-collapse,
.ipcs-group-shell .accordion-body,
.ipcs-module-collection--portal .ipcs-pp-tiles {
  min-width: 0;
}

/* 卡片只有約 320px 寬,標題 + 5 顆鈕擠同一行會把群組名壓成一字一行 → 允許工具列換到下一行 */
.ipcs-group-head {
  flex-wrap: wrap;
}

/* ── 群組不再是「框」,改成「分區標題」(使用者 2026-08-04:「外框包住類似資料夾概念,
   這樣會讓區域變小、功能磚變小」)──

   量出來的事實(1440px,Playwright 實測):卡寬 348px、卡內可用 298px。未分組時磚格是
   repeat(3,1fr) → 每顆磚 94px。一旦分組,磚格容器只剩 **226px**、每顆磚掉回 70px
   —— 縮水 26%。分組是為了更好找,結果東西變小更難點,目的與手段相反。

   兩個病因(下面兩條規則各治一個):

   ① **`.ipcs-group-shell` 根本沒有填滿卡片**(主因,72px)。它是 `__actions`(flex 容器)的
      子項,預設 `flex: 0 1 auto` = 縮到內容寬;內容的 max-content 又是磚的原生 70px×3
      → 整個群組區停在 226px。未分組那條路沒事,是因為 `.ipcs-pp-card` 早就被指定
      `flex: 1 1 100%`(本檔 :1887)。群組化之後 shell 取代它成為 flex 子項,卻沒繼承那個約定。

   ② **accordion 的框與內距再往內吃 42px**(accordion-body 左右各 1.25rem + item 邊框 1px×2)。

   ②的解法是拿掉「框」這個容器隱喻:群組改用**分區標題**表達(同 Slack 側邊欄區段 /
   iOS 設定分節),名稱與計數就是分界,不畫盒子 —— 於是群組內的磚與未分組的磚**等寬等大**。
   靠間距做歸屬:標題與自己的磚距離近(6px),群組之間距離遠(18px),Gestalt 的鄰近律
   足以分辨誰屬於誰,不需要外框。
   實作走**元件自己的 CSS 變數**而不是逐條覆蓋規則(模板優先原則):把 accordion 的邊框、
   底色、左右內距歸零,其餘(收合行為、chevron、無障礙屬性)完全沿用模板元件。 */
.ipcs-module-collection--portal .ipcs-group-shell {
  flex: 1 1 100%; /* 與 :1887 的 .ipcs-pp-card 同一個約定 —— 群組區也必須撐滿卡寬 */
}

/* 選擇器寫成 `.accordion.ipcs-group-accordion`(而不是單一 class)是為了穩穩蓋過 style.css
   的 `.accordion { --bs-accordion-* }` 基準值,不必依賴「哪個檔案後載入」。 */
.accordion.ipcs-group-accordion {
  --bs-accordion-border-width: 0;
  --bs-accordion-border-color: transparent;
  --bs-accordion-bg: transparent;
  --bs-accordion-btn-bg: transparent;
  --bs-accordion-active-bg: transparent;
  --bs-accordion-btn-padding-x: 0;
  --bs-accordion-btn-padding-y: 4px;
  --bs-accordion-body-padding-x: 0;
  --bs-accordion-body-padding-y: 6px;
  display: flex;
  flex-direction: column;
  gap: 18px; /* 群組之間拉開;標題→自己的磚只有 6px(body padding),近的才是一組 */
}

/* 展開中的標題底色是**唯一蓋不掉的變數**:style-preset.css 用 `[data-pc-preset=preset-1] .accordion`
   (特異度 0,2,0)指定 `--bs-accordion-active-bg: #e6f6fe`,壓過上面那組宣告 —— 沒有這條的話
   每個群組標題都會頂著一條淺藍長條,盒子的視覺又回來了。所以直接壓屬性,不繞變數。
   只壓底色:邊框寬度已歸零,模板那條 inset 邊線陰影自然不可見,焦點環也才留得住。 */
.ipcs-group-accordion .accordion-button:not(.collapsed) {
  background-color: transparent;
}

/* 沒有盒子之後,標題本身要撐起「這是一個分區」的份量 */
.ipcs-group-accordion .accordion-button {
  font-weight: 600;
}

/* 深色模式不必在這裡補文字色 —— 實測(Playwright,兩個主題各量一次):收合中的標題在深色下
   是 #bfbfbf(模板的深色主題自己有一條比 `--bs-accordion-btn-color` 更具體的規則在管),
   在 #19212a 上對比約 9:1;展開中的標題吃 accent #04A9F5,兩個主題都夠亮。
   曾經在這裡加過一條 `--bs-accordion-btn-color: #b0bec5`,量出來完全沒有作用 —— 別再加。 */

/* ── 群組收合改成滑順展開/收合(使用者 2026-07-29:「不要硬生生地直接收起」)──
   為什麼原本是硬切:Bootstrap 的收合動畫是 **JS 驅動的** —— `collapse.js` 會在過渡期間掛上
   `.collapsing` 並逐格改 height,CSS 只負責過渡。而群組手風琴刻意不掛 `data-bs-toggle`
   (收合的真相是 React 的 `group.collapsed`,不讓 Bootstrap 自己再管一份狀態),
   於是只有 `.show` 被加減,`.collapse:not(.show){display:none}` 直接把整塊切掉。

   解法用 `grid-template-rows: 0fr → 1fr` 而不是 max-height:
   max-height 得猜一個「夠大」的值,猜小了內容被裁、猜大了收合速度前半段是空跑;
   0fr→1fr 由瀏覽器自己算真實高度,15 顆磚跟 1 顆磚的手感一致。
   padding 必須一起過渡 —— 否則 0fr 時 accordion-body 的上下內距仍會留下一條空白。 */
.ipcs-group-accordion .accordion-collapse {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.28s ease;
}
.ipcs-group-accordion .accordion-collapse.show {
  grid-template-rows: 1fr;
}
.ipcs-group-accordion .accordion-collapse > .accordion-body {
  overflow: hidden;
  min-height: 0; /* grid 子項預設 min-height:auto,不歸零就壓不到 0 */
  transition: padding-top 0.28s ease, padding-bottom 0.28s ease;
}
.ipcs-group-accordion .accordion-collapse:not(.show) > .accordion-body {
  padding-top: 0;
  padding-bottom: 0;
}

/* 會暈眩的人把動畫關掉(作業系統層級的偏好),收合本身仍然有效 */
@media (prefers-reduced-motion: reduce) {
  .ipcs-group-accordion .accordion-collapse,
  .ipcs-group-accordion .accordion-collapse > .accordion-body {
    transition: none;
  }
}

/* 編輯模式下磚外面多包的 .ipcs-pp-tile-wrap 必須「當成磚本人」參與格線。
   產品 panel 的磚格是 grid-template-columns: repeat(3, 1fr)(:1887),而 wrap 原本是
   inline-flex、沒有寬度約束 —— 內層 .ipcs-pp-tile 在這個 grid 內被改成 width:auto +
   aspect-ratio:1/1(:1892),於是它反過來去撐 wrap,整排磚溢出卡片。
   2026-07-28 實測:1440px 下編輯模式磚最右超出卡片右緣 54px(非編輯模式是 -25px,正常)。
   這是編輯模式一開始就有的問題,不是這次改版造成的。 */
.ipcs-module-collection--portal .ipcs-pp-tiles .ipcs-pp-tile-wrap {
  display: flex;
  width: 100%;
  min-width: 0;
}
.ipcs-module-collection--portal .ipcs-pp-tiles .ipcs-pp-tile-wrap > .ipcs-pp-tile {
  width: 100%;
}

/* ── 「整理功能群組」大視窗(GroupEditModal,2026-08-04)──
   磚格的等分格線規則原本 scope 在 `.ipcs-module-collection--portal`(本檔 :1890),
   視窗不在那個容器裡 → 不加這一段的話,磚會掉回 `.ipcs-pp-tile` 的原生 70px 定寬 flex,
   而編輯模式外面多包的 `.ipcs-pp-tile-wrap`(inline-flex、無寬度約束)會跟磚打架。
   這裡是同一組規則換一個 scope,不是新視覺:唯一的差別是欄寬改成 auto-fill —— 視窗有
   modal-lg 的寬度可用,寫死 3 欄反而浪費;minmax 讓它自己決定一列放幾顆。 */
.ipcs-group-modal .ipcs-pp-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 10px;
}
.ipcs-group-modal .ipcs-pp-tiles .ipcs-pp-tile:not(.ipcs-pp-tile--enter) {
  width: auto;
  height: auto;
  aspect-ratio: 1 / 1;
}
.ipcs-group-modal .ipcs-pp-tiles .ipcs-pp-tile-wrap {
  display: flex;
  width: 100%;
  min-width: 0;
}
.ipcs-group-modal .ipcs-pp-tiles .ipcs-pp-tile-wrap > .ipcs-pp-tile {
  width: 100%;
}
/* `.ipcs-group-head` 的 flex-wrap 是為了 300px 的卡片開的(標題 + 三顆鈕擠不下才換行)。
   視窗有 800px,再讓工具列自己掉一行只是浪費一整列並讓「這幾顆鈕屬於哪一組」變模糊。 */
.ipcs-group-modal .ipcs-group-head {
  flex-wrap: nowrap;
}

/* 整系統入口那顆不可分群,在視窗裡純粹是「這張卡長這樣」的脈絡 —— 拉成整列的橫向大鈕
   (與產品分頁 :1869 同一個處理),免得它混在可搬的方磚之間被誤以為也能拖。 */
.ipcs-group-modal .ipcs-pp-tile--enter {
  grid-column: 1 / -1;
  width: 100%;
  height: 62px;
  aspect-ratio: auto;
  flex-direction: row;
  gap: 8px;
}
.ipcs-group-modal .ipcs-pp-tile--enter .ipcs-pp-tile__name {
  width: auto;
  font-size: 0.95rem;
}

/* 磚上的多選勾選框:與「⋮」對稱放在左上角,不與它搶位置 */
.ipcs-pp-tile-select {
  position: absolute;
  top: -6px;
  left: -6px;
  z-index: 5;
  margin: 0;
  line-height: 0;
  cursor: pointer;
}
.ipcs-pp-tile-select .form-check-input {
  margin: 0;
  cursor: pointer;
}
.ipcs-pp-tile-wrap.is-selected .ipcs-pp-tile {
  border-color: var(--ipcs-accent);
  box-shadow: 0 0 0 2px var(--ipcs-accent-soft);
}

/* 常用區的並排磚 (使用者 2026-06-29):原本 list-group 原生外框太貼太硬,
   改成卡片式 — 柔和邊框 + 12px 圓角 + 淡陰影 + hover 微浮起 (對齊模板 token)。 */
.ipcs-quicklaunch-item {
  padding: 13px 16px;
  border: 1px solid #e8edf2;
  border-radius: 12px;
  background: #fff;
  color: inherit;
  box-shadow: 0px 4px 14px rgba(41, 52, 74, 0.05);
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}
/* H6 hover 治理::hover 與 :focus-visible 原本合併宣告,拆開避免鍵盤 focus 樣式被誤包進
   @media(hover:hover) 而消失(focus-visible 不分裝置都要保留,是鍵盤/切換器操作的必要提示)。 */
@media (hover: hover) and (pointer: fine) {
  .ipcs-quicklaunch-item:hover {
    border-color: var(--ipcs-accent-border);
    box-shadow: 0px 8px 20px rgba(41, 52, 74, 0.12);
    transform: translateY(-2px);
    outline: none;
  }
}
.ipcs-quicklaunch-item:focus-visible {
  border-color: var(--ipcs-accent-border);
  box-shadow: 0px 8px 20px rgba(41, 52, 74, 0.12);
  transform: translateY(-2px);
  outline: none;
}
.ipcs-quicklaunch-item:disabled {
  cursor: default;
  transform: none;
  box-shadow: 0px 4px 14px rgba(41, 52, 74, 0.05);
}
body[data-pc-theme='dark'] .ipcs-quicklaunch-item {
  border-color: #303f50;
  background: #1f2832;
  box-shadow: 0px 4px 14px rgba(0, 0, 0, 0.3);
}
@media (hover: hover) and (pointer: fine) {
  body[data-pc-theme='dark'] .ipcs-quicklaunch-item:hover {
    border-color: color-mix(in srgb, var(--ipcs-accent) 42%, transparent);
    box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.45);
  }
}
body[data-pc-theme='dark'] .ipcs-quicklaunch-item:focus-visible {
  border-color: color-mix(in srgb, var(--ipcs-accent) 42%, transparent);
  box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.45);
}

/* 右上角「另開新視窗」箭頭 — 使用者 2026-06-26 覺得太雜,方磚一律隱藏這顆小箭頭
   (另開行為仍由 title tooltip 說明)。要恢復就把 display 改回來。 */
.ipcs-pp-tile__out {
  display: none;
}

/* 「更多」磚:虛線灰調,點開功能選單 */
.ipcs-pp-tile--more {
  border-style: dashed;
  border-color: #cbd5e1;
  background: #f8fafc;
  color: #64748b;
}

@media (hover: hover) and (pointer: fine) {
  .ipcs-pp-tile--more:hover {
    background: #eef2f7;
    color: #475569;
    box-shadow: none;
  }
}
.ipcs-pp-tile--more:focus-visible {
  background: #eef2f7;
  color: #475569;
  box-shadow: none;
}

/* 已訂閱但此子模組尚無入口 → 灰磚,不可點、不浮起 (產品中心子模組用) */
.ipcs-pp-tile--disabled {
  background: #f1f5f9;
  border-color: #e2e8f0;
  color: #94a3b8;
  cursor: default;
}
@media (hover: hover) and (pointer: fine) {
  .ipcs-pp-tile--disabled:hover {
    background: #f1f5f9;
    color: #94a3b8;
    transform: none;
    box-shadow: none;
  }
}
.ipcs-pp-tile--disabled:focus-visible {
  background: #f1f5f9;
  color: #94a3b8;
  transform: none;
  box-shadow: none;
}
/* 雙 class 提高權重 → 蓋過後面通用的 body[dark] .ipcs-pp-tile 藍底,確保灰磚在深色維持中性 */
body[data-pc-theme='dark'] .ipcs-pp-tile.ipcs-pp-tile--disabled {
  background: #232c37;
  border-color: #3a4757;
  color: #6b7a8d;
}
@media (hover: hover) and (pointer: fine) {
  body[data-pc-theme='dark'] .ipcs-pp-tile.ipcs-pp-tile--disabled:hover {
    background: #232c37;
    color: #6b7a8d;
    transform: none;
    box-shadow: none;
  }
}
body[data-pc-theme='dark'] .ipcs-pp-tile.ipcs-pp-tile--disabled:focus-visible {
  background: #232c37;
  color: #6b7a8d;
  transform: none;
  box-shadow: none;
}

/* 了解更多 / 操作教學 磚:中性灰調,跟入口藍磚明顯區隔 (使用者 2026-06-25) */
.ipcs-pp-tile--doc {
  background: #f1f5f9;
  border-color: #e2e8f0;
  color: #52647a;
}
@media (hover: hover) and (pointer: fine) {
  .ipcs-pp-tile--doc:hover {
    background: #e7edf3;
    color: #334155;
  }
}
.ipcs-pp-tile--doc:focus-visible {
  background: #e7edf3;
  color: #334155;
}
body[data-pc-theme='dark'] .ipcs-pp-tile.ipcs-pp-tile--doc {
  background: #232c37;
  border-color: #3a4757;
  color: #aebccd;
}
@media (hover: hover) and (pointer: fine) {
  body[data-pc-theme='dark'] .ipcs-pp-tile.ipcs-pp-tile--doc:hover {
    background: #2b3542;
    color: #dbe4ee;
  }
}
body[data-pc-theme='dark'] .ipcs-pp-tile.ipcs-pp-tile--doc:focus-visible {
  background: #2b3542;
  color: #dbe4ee;
}

.ipcs-pp-card--disabled {
  background: #f8fafc;
  border-style: dashed;
}

body[data-pc-theme='dark'] .ipcs-pp-card {
  border-color: #303f50;
  background: #1f2832;
}

body[data-pc-theme='dark'] .ipcs-pp-card--disabled {
  background: #1a222c;
}

body[data-pc-theme='dark'] .ipcs-pp-card__name {
  color: #e2e8f0;
}

/* dark mode:功能方磚吃 --ipcs-accent(產品品牌色 / preset),用 color-mix 提亮在深底可讀,換配色就跟著變 (使用者 2026-06-29) */
body[data-pc-theme='dark'] .ipcs-pp-tile {
  background: color-mix(in srgb, var(--ipcs-accent) 16%, transparent);
  border-color: color-mix(in srgb, var(--ipcs-accent) 32%, transparent);
  color: color-mix(in srgb, var(--ipcs-accent) 42%, white);
}

@media (hover: hover) and (pointer: fine) {
  body[data-pc-theme='dark'] .ipcs-pp-tile:hover {
    background: var(--ipcs-accent);
    border-color: var(--ipcs-accent);
    color: #fff;
  }
}
body[data-pc-theme='dark'] .ipcs-pp-tile:focus-visible {
  background: var(--ipcs-accent);
  border-color: var(--ipcs-accent);
  color: #fff;
}

body[data-pc-theme='dark'] .ipcs-pp-tile--more {
  background: #232c37;
  border-color: #3a4757;
  color: #9fb0c3;
}

@media (hover: hover) and (pointer: fine) {
  body[data-pc-theme='dark'] .ipcs-pp-tile--more:hover {
    background: #2b3542;
    color: #cdd8e4;
  }
}
body[data-pc-theme='dark'] .ipcs-pp-tile--more:focus-visible {
  background: #2b3542;
  color: #cdd8e4;
}

/* 模組卡 __actions 內重用功能磚:--bare 去掉卡邊/底色/padding,只留 position:relative(供 popover 定位)
   與 flex 直向結構,並當 JS 的 .ipcs-pp-card 錨點。產品分頁與產品中心共用 (使用者 2026-06-25) */
.ipcs-pp-card--bare {
  padding: 0;
  border: none;
  background: transparent;
}

body[data-pc-theme='dark'] .ipcs-pp-card--bare {
  border-color: transparent;
  background: transparent;
}

/* 產品中心:啟動磚一列、了解更多/操作教學一列,直向堆疊 */
.ipcs-pp-actions {
  flex-direction: column;
  align-items: flex-start;
}

.ipcs-pp-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ipcs-card-title-link {
  color: #233548;
  text-decoration: none;
}

.ipcs-card-title-link:hover {
  color: var(--ipcs-accent);
}

/* 常用 quick-launch 已改用模板原生 list-group + avtar + badge (使用者 2026-06-23),
   自訂磚樣式整組移除;改由 Bootstrap/Light Able 元件處理,自動跟 light/dark。 */

/* ── 釘選鈕(訂選):釘選後吃 accent 色,卡片排到清單最前 ── */
.ipcs-pin-btn.is-pinned {
  border-color: var(--ipcs-accent-border);
  background: var(--ipcs-accent-soft);
  color: var(--ipcs-accent);
}

.ipcs-boundary-overlay {
  position: fixed;
  inset: 0;
  z-index: 1080;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(10px);
}

.ipcs-boundary-card {
  width: min(420px, 100%);
  display: grid;
  justify-items: center;
  gap: 14px;
  padding: 28px;
  border-radius: 12px;
  border: 1px solid rgba(216, 224, 231, 0.9);
  background: rgba(255, 255, 255, 0.98);
  box-shadow: 0px 8px 24px rgba(41, 52, 74, 0.12);
  text-align: center;
}

.ipcs-boundary-spinner {
  width: 42px;
  height: 42px;
  border-radius: 999px;
  border: 3px solid rgba(27, 127, 204, 0.16);
  border-top-color: #1b6ca8;
  animation: ipcs-boundary-spin 0.72s linear infinite;
}

@keyframes ipcs-boundary-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ── Payment method brand colors (light mode) ── */

/* ── Credit card form ── */

body[data-pc-theme='dark'] .ipcs-topbar-current-workspace {
  background: transparent;
}

body[data-pc-theme='dark'] .ipcs-topbar-current-workspace > i {
  color: #9fb6cd;
}

body[data-pc-theme='dark'] .ipcs-login-link {
  color: #8cc2ff;
}

body[data-pc-theme='dark'] .ipcs-quick-step,
body[data-pc-theme='dark'] .ipcs-backoffice-project-card {
  border-color: #303f50;
  background: #1b232d;
}

body[data-pc-theme='dark'] .ipcs-backoffice-project-card {
  border-color: #303f50;
  background: #1b232d;
}

body[data-pc-theme='dark'] .ipcs-sidebar-mode-button,
body[data-pc-theme='dark'] .ipcs-boundary-card {
  border-color: #303f50;
  background: #1b232d;
  color: #e2e8f0;
}

/* 深色模式 active tab 也吃 preset 主色:用 color-mix 把主色提亮成淺色文字 (深底可讀),
   背景/邊框用主色半透明 tint,換配色時深色按鈕跟著變 (使用者 2026-06-29) */
body[data-pc-theme='dark'] .ipcs-sidebar-mode-button.is-active {
  border-color: color-mix(in srgb, var(--ipcs-accent) 42%, transparent);
  background: color-mix(in srgb, var(--ipcs-accent) 22%, transparent);
  color: color-mix(in srgb, var(--ipcs-accent) 35%, white);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ipcs-accent) 12%, transparent);
}

body[data-pc-theme='dark'] .ipcs-card-title-link {
  color: #edf3f7;
}

body[data-pc-theme='dark'] .ipcs-card-title-link:hover {
  color: color-mix(in srgb, var(--ipcs-accent) 35%, white);
}

body[data-pc-theme='dark'] .ipcs-modules-search {
  border-color: #303f50;
  background: #1b232d;
  color: #cbd5e1;
}

body[data-pc-theme='dark'] .ipcs-modules-search i,
body[data-pc-theme='dark'] .ipcs-modules-search input {
  color: #e2e8f0;
}

@media (max-width: 1199px) {
  .ipcs-portal-grid,
.ipcs-product-facts,
.ipcs-product-grid {
    grid-template-columns: 1fr;
  }

  

  

  .ipcs-module-collection {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 991px) {
  .ipcs-product-head,
.ipcs-product-head__identity,
.ipcs-section-head {
    flex-direction: column;
    align-items: stretch;
  }

  

  .ipcs-topbar-current-workspace {
    min-width: auto;
    padding-inline: 12px;
  }

  .ipcs-module-collection,
  .ipcs-module-collection.is-list-view {
    grid-template-columns: 1fr;
  }

  

  .ipcs-module-collection.is-list-view .ipcs-module-card-clean .card-body {
    flex-direction: column;
    align-items: stretch;
  }

  .ipcs-module-collection.is-list-view .ipcs-module-card-clean__actions {
    min-width: 0;
    justify-content: flex-start;
  }
}

@media (max-width: 767.98px) {
  .ipcs-social-login {
    justify-content: center;
    padding-inline: 12px;
    font-size: 0.95rem;
  }

  
}

@media (max-width: 767px) {
  .ipcs-modules-page__head,
  .ipcs-modules-toolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .ipcs-topbar-bar__center {
    justify-content: flex-start;
  }

  

  .ipcs-topbar-current-workspace .ipcs-topbar-pill__copy strong {
    font-size: 1.08rem;
  }

  .ipcs-login-form-shell .card-body {
    padding: 28px 22px;
  }

  .ipcs-sidebar-toggle {
    grid-template-columns: 1fr;
  }
}

.ipcs-learning-grid {
  display: grid;
  gap: 1.25rem;
}

.ipcs-learning-card {
  border: 1px solid rgba(15, 23, 42, 0.08);
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.98));
  padding: 1.25rem;
  display: grid;
  gap: 1rem;
}

.ipcs-learning-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.ipcs-learning-list,
.ipcs-faq-stack {
  display: grid;
  gap: 0.75rem;
}

.ipcs-learning-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.875rem;
  align-items: center;
  padding: 0.875rem 1rem;
  border-radius: 18px;
  background: rgba(248, 250, 252, 0.96);
  border: 1px solid rgba(148, 163, 184, 0.22);
}

.ipcs-learning-item__icon {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(37, 99, 235, 0.12);
  color: #2563eb;
  font-size: 1.25rem;
}

.ipcs-learning-item__body {
  display: grid;
  gap: 0.2rem;
}

.ipcs-learning-item__body strong {
  color: #0f172a;
  font-size: 0.96rem;
}

.ipcs-learning-item__body span {
  color: #39465F;
  font-size: 0.85rem;
  line-height: 1.5;
}

.ipcs-faq-item {
  border: 1px solid rgba(148, 163, 184, 0.22);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.96);
  padding: 0.95rem 1rem;
}

.ipcs-faq-item summary {
  list-style: none;
  cursor: pointer;
  font-weight: 600;
  color: #0f172a;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.ipcs-faq-item summary::-webkit-details-marker {
  display: none;
}

.ipcs-faq-item summary::after {
  content: "+";
  color: #2563eb;
  font-size: 1.15rem;
  line-height: 1;
}

.ipcs-faq-item[open] summary::after {
  content: "−";
}

.ipcs-faq-item p {
  margin: 0.75rem 0 0;
  color: #39465F;
  line-height: 1.65;
}

body[data-pc-theme='dark'] .ipcs-learning-card {
  background: #1b232d;
  border-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-learning-item,
body[data-pc-theme='dark'] .ipcs-faq-item {
  background: #1b232d;
  border-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-learning-item__body strong,
body[data-pc-theme='dark'] .ipcs-faq-item summary {
  color: #e2e8f0;
}

body[data-pc-theme='dark'] .ipcs-learning-item__body span,
body[data-pc-theme='dark'] .ipcs-faq-item p {
  color: #748892;
}

body[data-pc-theme='dark'] .ipcs-learning-item__icon {
  background: rgba(59, 130, 246, 0.18);
  color: #93c5fd;
}

:root {
  --ipcs-accent: #1b6ca8;
  --ipcs-accent-strong: #145785;
  --ipcs-accent-soft: rgba(27, 127, 204, 0.12);
  --ipcs-accent-border: rgba(27, 127, 204, 0.22);
}

body[data-pc-preset='preset-1'] {
  --ipcs-accent: #04a9f5;
  --ipcs-accent-strong: #0387c4;
  --ipcs-accent-soft: rgba(4, 169, 245, 0.12);
  --ipcs-accent-border: rgba(4, 169, 245, 0.22);
}

body[data-pc-preset='preset-2'] {
  --ipcs-accent: #6610f2;
  --ipcs-accent-strong: #520dc2;
  --ipcs-accent-soft: rgba(102, 16, 242, 0.12);
  --ipcs-accent-border: rgba(102, 16, 242, 0.22);
}

body[data-pc-preset='preset-3'] {
  --ipcs-accent: #673ab7;
  --ipcs-accent-strong: #522e92;
  --ipcs-accent-soft: rgba(103, 58, 183, 0.12);
  --ipcs-accent-border: rgba(103, 58, 183, 0.22);
}

body[data-pc-preset='preset-4'] {
  --ipcs-accent: #e83e8c;
  --ipcs-accent-strong: #d63384;
  --ipcs-accent-soft: rgba(232, 62, 140, 0.12);
  --ipcs-accent-border: rgba(232, 62, 140, 0.22);
}

body[data-pc-preset='preset-5'] {
  --ipcs-accent: #f44236;
  --ipcs-accent-strong: #d9372d;
  --ipcs-accent-soft: rgba(244, 66, 54, 0.12);
  --ipcs-accent-border: rgba(244, 66, 54, 0.22);
}

body[data-pc-preset='preset-6'] {
  --ipcs-accent: #fd7e14;
  --ipcs-accent-strong: #e56d00;
  --ipcs-accent-soft: rgba(253, 126, 20, 0.12);
  --ipcs-accent-border: rgba(253, 126, 20, 0.22);
}

body[data-pc-preset='preset-7'] {
  --ipcs-accent: #f4c22b;
  --ipcs-accent-strong: #d8a400;
  --ipcs-accent-soft: rgba(244, 194, 43, 0.12);
  --ipcs-accent-border: rgba(244, 194, 43, 0.22);
}

body[data-pc-preset='preset-8'] {
  --ipcs-accent: #1de9b6;
  --ipcs-accent-strong: #10b981;
  --ipcs-accent-soft: rgba(29, 233, 182, 0.12);
  --ipcs-accent-border: rgba(29, 233, 182, 0.22);
}

body[data-pc-preset='preset-9'] {
  --ipcs-accent: #008080;
  --ipcs-accent-strong: #006666;
  --ipcs-accent-soft: rgba(0, 128, 128, 0.12);
  --ipcs-accent-border: rgba(0, 128, 128, 0.22);
}

body[data-pc-preset='preset-10'] {
  --ipcs-accent: #3ebfea;
  --ipcs-accent-strong: #289dc5;
  --ipcs-accent-soft: rgba(62, 191, 234, 0.12);
  --ipcs-accent-border: rgba(62, 191, 234, 0.22);
}

body {
  --ipcs-button: var(--ipcs-accent);
  --ipcs-button-strong: var(--ipcs-accent-strong);
  --ipcs-button-soft: var(--ipcs-accent-soft);
  --ipcs-button-border: var(--ipcs-accent-border);
}

body[data-ipcs-accent='ocean'] {
  --ipcs-accent: #1b6ca8;
  --ipcs-accent-strong: #145785;
  --ipcs-accent-soft: rgba(27, 108, 168, 0.12);
  --ipcs-accent-border: rgba(27, 108, 168, 0.24);
}

body[data-ipcs-accent='emerald'] {
  --ipcs-accent: #15735b;
  --ipcs-accent-strong: #0f5845;
  --ipcs-accent-soft: rgba(21, 115, 91, 0.12);
  --ipcs-accent-border: rgba(21, 115, 91, 0.24);
}

body[data-ipcs-accent='amber'] {
  --ipcs-accent: #a56b12;
  --ipcs-accent-strong: #83530d;
  --ipcs-accent-soft: rgba(165, 107, 18, 0.12);
  --ipcs-accent-border: rgba(165, 107, 18, 0.24);
}

body[data-ipcs-accent='slate'] {
  --ipcs-accent: #39465F;
  --ipcs-accent-strong: #334155;
  --ipcs-accent-soft: rgba(71, 85, 105, 0.12);
  --ipcs-accent-border: rgba(71, 85, 105, 0.24);
}

body[data-ipcs-button-tone='ocean'] {
  --ipcs-button: #1b6ca8;
  --ipcs-button-strong: #145785;
  --ipcs-button-soft: rgba(27, 108, 168, 0.12);
  --ipcs-button-border: rgba(27, 108, 168, 0.24);
}

body[data-ipcs-button-tone='emerald'] {
  --ipcs-button: #15735b;
  --ipcs-button-strong: #0f5845;
  --ipcs-button-soft: rgba(21, 115, 91, 0.12);
  --ipcs-button-border: rgba(21, 115, 91, 0.24);
}

body[data-ipcs-button-tone='amber'] {
  --ipcs-button: #a56b12;
  --ipcs-button-strong: #83530d;
  --ipcs-button-soft: rgba(165, 107, 18, 0.12);
  --ipcs-button-border: rgba(165, 107, 18, 0.24);
}

body[data-ipcs-button-tone='slate'] {
  --ipcs-button: #39465F;
  --ipcs-button-strong: #334155;
  --ipcs-button-soft: rgba(71, 85, 105, 0.12);
  --ipcs-button-border: rgba(71, 85, 105, 0.24);
}

.pc-header .btn-primary,
.pc-sidebar .btn-primary,
.pc-container .btn-primary {
  background: var(--ipcs-button);
  border-color: var(--ipcs-button);
}

.pc-header .btn-primary:hover,
.pc-sidebar .btn-primary:hover,
.pc-container .btn-primary:hover,
.pc-header .btn-primary:focus,
.pc-sidebar .btn-primary:focus,
.pc-container .btn-primary:focus {
  background: var(--ipcs-button-strong);
  border-color: var(--ipcs-button-strong);
}

.pc-header .btn-light-primary,
.pc-sidebar .btn-light-primary,
.pc-container .btn-light-primary {
  color: var(--ipcs-button);
  border-color: var(--ipcs-button-border);
  background: var(--ipcs-button-soft);
}

.pc-header .btn-light-primary:hover,
.pc-sidebar .btn-light-primary:hover,
.pc-container .btn-light-primary:hover {
  color: #fff;
  border-color: var(--ipcs-button);
  background: var(--ipcs-button);
}

.ipcs-state-badge {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 0.45em 0.8em;
  border-radius: 6px;
  border: 1px solid transparent;
  font-size: 0.75rem;
  font-weight: 500;
}

.ipcs-state-badge--purchased {
  color: #0f766e;
  border-color: rgba(15, 118, 110, 0.2);
  background: rgba(15, 118, 110, 0.1);
}

.ipcs-state-badge--expired {
  color: #b42318;
  border-color: rgba(180, 35, 24, 0.18);
  background: rgba(180, 35, 24, 0.1);
}

/* 尚未開通 / 未訂閱 — 中性灰(資訊性) */
.ipcs-state-badge--unpurchased {
  color: #5a6b7a;
  border-color: rgba(100, 116, 139, 0.22);
  background: rgba(100, 116, 139, 0.1);
}

/* 需申請使用權限 — 琥珀(可操作) */
.ipcs-state-badge--restricted {
  color: #b45309;
  border-color: rgba(245, 158, 11, 0.26);
  background: rgba(245, 158, 11, 0.12);
}

/* ─── SysAdmin/Modules 卡片 useScenes inline CRUD 控件 ─── */
/* scene pill 內的「移除」按鈕:預設 hidden (沒外框、文字),sys-edit-mode 才顯示 icon */
.ipcs-sys-mod-card__scene-remove {
  display: none;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: #b42318;
  padding: 0;
  margin-left: 4px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 10px;
  line-height: 1;
  transition: background 0.15s, color 0.15s;
}
body.sys-edit-mode .ipcs-sys-mod-card__scene-remove {
  display: inline-flex;
}
.ipcs-sys-mod-card__scene-remove:hover {
  background: rgba(180, 35, 24, 0.12);
  color: #b42318;
}

/* 「+ 新增情境」按鈕:預設 hidden,sys-edit-mode 才顯示 */
.ipcs-sys-mod-card__scene-add {
  display: none;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 1px dashed var(--bs-border-color);
  color: var(--bs-secondary-color, #5a6b7a);
  padding: 4px 10px;
  border-radius: 14px;
  cursor: pointer;
  font-size: 12px;
  transition: border-color 0.15s, color 0.15s;
}
body.sys-edit-mode .ipcs-sys-mod-card__scene-add {
  display: inline-flex;
}
.ipcs-sys-mod-card__scene-add:hover {
  border-color: var(--ipcs-accent, #04A9F5);
  color: var(--ipcs-accent, #04A9F5);
}

/* 檢視模式下「尚未設定使用情境」hint 不顯示 (沒情境就乾脆整塊隱藏) */
.ipcs-sys-mod-card__scenes-empty {
  display: none;
}
body.sys-edit-mode .ipcs-sys-mod-card__scenes-empty {
  display: inline;
}

/* ─── 登入中 Loading Modal spinner 動畫 ─── */
@keyframes ipcsSpin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* ─── 多公司選擇 Modal — 公司卡片 ─── */
.ipcs-org-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.ipcs-org-card {
  background: var(--bs-card-bg, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 10px;
  padding: 16px;
  text-align: left;
  cursor: pointer;
  transition: all .18s;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
@media (hover: hover) and (pointer: fine) {
  .ipcs-org-card:hover {
    border-color: var(--ipcs-accent, #04A9F5);
    background: var(--bs-tertiary-bg);
    transform: translateY(-1px);
  }
}
.ipcs-org-card--loading {
  opacity: 0.6;
  cursor: progress;
}
.ipcs-org-card__head {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ipcs-org-card__head strong { font-size: 15px; }
.ipcs-org-card__head small { color: var(--bs-secondary-color); font-size: 11px; letter-spacing: 1px; font-family: monospace; }
.ipcs-org-card__systems {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.ipcs-org-card__sys-pill {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(4,169,245,0.1);
  color: var(--ipcs-accent, #04A9F5);
  border: 1px solid rgba(4,169,245,0.2);
}

/* ─── 內容區最小高度與底部留白 ───
   原本是 sticky footer 用的(頁尾 2026-10-02 整個拿掉,使用者:登入後的系統不要有頁尾)。
   flex 直排與最小高度照舊保留:各頁的空狀態、骨架屏是照這個版面調的,拿掉會讓短頁面的排版跟著變。 */
.pc-content {
  min-height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
  /* 底部留白(10-05 補):頁尾拿掉之後,每一頁最後一張卡片都貼著畫面底部(使用者發現)。24px = 模板卡片之間的間距 */
  padding-bottom: 24px;
}

.ipcs-state-badge--billing {
  color: var(--ipcs-accent);
  border-color: var(--ipcs-accent-border);
  background: var(--ipcs-accent-soft);
}

.ipcs-module-card-clean__surface {
  display: block;
  color: inherit;
  text-decoration: none;
}

.ipcs-module-card-clean__surface:hover .ipcs-card-title-link {
  color: var(--ipcs-accent);
}

.ipcs-module-card-clean--locked {
  position: relative;
  opacity: 0.92;
}

.ipcs-module-card-clean--locked::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 12px;
  border: 1px solid rgba(180, 35, 24, 0.12);
  pointer-events: none;
}

.ipcs-module-scene-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ipcs-module-scene-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: 999px;
  background: #F4F7FA;
  border: 1px solid #e2e8f0;
  color: #39465F;
  font-size: 0.8rem;
}

.ipcs-product-feature-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.ipcs-product-feature-card {
  padding: 18px;
  border-radius: 18px;
  border: 1px solid #e5ebf0;
  background: #fbfcfd;
}

.ipcs-summary-row--stacked {
  justify-content: flex-start;
}

.ipcs-accent-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.ipcs-accent-option {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 0 14px;
  border-radius: 16px;
  border: 1px solid #d8e0e7;
  background: #fff;
  color: #334155;
  font-weight: 600;
}

.ipcs-accent-option.is-active {
  border-color: var(--ipcs-accent-border);
  background: var(--ipcs-accent-soft);
  color: var(--ipcs-accent);
}

.ipcs-accent-option__swatch {
  width: 18px;
  height: 18px;
  border-radius: 999px;
  display: inline-block;
}

.ipcs-accent-option__swatch--ocean { background: #1b6ca8; }
.ipcs-accent-option__swatch--emerald { background: #15735b; }
.ipcs-accent-option__swatch--amber { background: #a56b12; }
.ipcs-accent-option__swatch--slate { background: #39465F; }

body[data-pc-theme='dark'] .pc-sidebar {
  background: #1d2630;
  border-right-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-state-badge--purchased {
  color: #99f6e4;
  background: rgba(13, 148, 136, 0.2);
  border-color: rgba(45, 212, 191, 0.28);
}

body[data-pc-theme='dark'] .ipcs-state-badge--expired {
  color: #fecaca;
  background: rgba(185, 28, 28, 0.22);
  border-color: rgba(248, 113, 113, 0.28);
}

body[data-pc-theme='dark'] .ipcs-state-badge--unpurchased {
  color: #cbd5e1;
  background: rgba(148, 163, 184, 0.16);
  border-color: rgba(148, 163, 184, 0.3);
}

body[data-pc-theme='dark'] .ipcs-state-badge--restricted {
  color: #fcd9a8;
  background: rgba(180, 120, 20, 0.24);
  border-color: rgba(245, 158, 11, 0.32);
}

body[data-pc-theme='dark'] .ipcs-state-badge--billing,
body[data-pc-theme='dark'] .ipcs-accent-option.is-active {
  color: #bfdbfe;
  background: rgba(96, 165, 250, 0.14);
  border-color: rgba(96, 165, 250, 0.24);
}

/* 產品中心「未訂閱 / 無存取權」徽章用原生 .badge.bg-light-secondary.text-secondary,
   .text-secondary 工具類帶 !important 把文字鎖成淺色模式灰(深色模式對比僅 ~2.6:1,看不清)。
   必須用 !important + 更高 specificity 才壓得過,提亮到過 AA。 */
body[data-pc-theme='dark'] .badge.bg-light-secondary.text-secondary,
body[data-pc-theme='dark'] .badge.bg-light-secondary {
  color: #94a3b8 !important;
}

body[data-pc-theme='dark'] .ipcs-module-scene-pill,
body[data-pc-theme='dark'] .ipcs-product-feature-card,
body[data-pc-theme='dark'] .ipcs-accent-option,
body[data-pc-theme='dark'] .ipcs-ws-card {
  color: #cbd5e1;
  background: #1b232d;
  border-color: #303f50;
}

/* ── Dark mode: comprehensive text & background overrides ── */

body[data-pc-theme='dark'] .ipcs-form-label {
  color: #748892;
}

body[data-pc-theme='dark'] .ipcs-ws-header h4 {
  color: #edf3f7;
}

body[data-pc-theme='dark'] .ipcs-ws-header p {
  color: #748892;
}

body[data-pc-theme='dark'] .ipcs-ws-card__name strong {
  color: #edf3f7;
}

body[data-pc-theme='dark'] .ipcs-ws-card__desc {
  color: #748892;
}

body[data-pc-theme='dark'] .ipcs-ws-card__status {
  color: #748892;
}

body[data-pc-theme='dark'] .ipcs-ws-card__type {
  background: rgba(255, 255, 255, 0.08);
  color: #cbd5e1;
}

body[data-pc-theme='dark'] .ipcs-ws-card__footer {
  border-top-color: #303f50;
}

/* Dark mode: solid cards stay the same gradient, just darken slightly */
body[data-pc-theme='dark'] .ipcs-ws-card--warning { background: linear-gradient(135deg, #78350f, #a16207); }
body[data-pc-theme='dark'] .ipcs-ws-card--primary { background: linear-gradient(135deg, #172554, #2563eb); }
body[data-pc-theme='dark'] .ipcs-ws-card--success { background: linear-gradient(135deg, #052e16, #059669); }
body[data-pc-theme='dark'] .ipcs-ws-card--danger { background: linear-gradient(135deg, #7f1d1d, #dc2626); }
body[data-pc-theme='dark'] .ipcs-ws-card--info { background: linear-gradient(135deg, #0e3a4a, #0891b2); }

body[data-pc-theme='dark'] .ipcs-ws-card--create {
  border-color: #303f50;
  background: transparent;
}
@media (hover: hover) and (pointer: fine) {
  body[data-pc-theme='dark'] .ipcs-ws-card--create:hover {
    border-color: #04A9F5;
    background: rgba(4, 169, 245, 0.08);
  }
}
body[data-pc-theme='dark'] .ipcs-ws-card--create .ipcs-ws-card__name strong {
  color: #cbd5e1;
}
body[data-pc-theme='dark'] .ipcs-ws-card--create .ipcs-ws-card__desc {
  color: #8a9bae;
}

/* 用完整 .auth-form .card 鏈,特異度才壓得過 light 的 432 行(border:1px solid rgba(216,224,231,.95)),
   否則深色卡片會被亮色 border 框住像發光外框。 */
body[data-pc-theme='dark'] .auth-main.v2.ipcs-auth-shell .auth-form .card,
body[data-pc-theme='dark'] .ipcs-login-form-shell .card {
  background: #1b232d;
  border-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-login-link {
  color: #748892;
}

body[data-pc-theme='dark'] .ipcs-social-login {
  border-color: #303f50;
  background: rgba(255, 255, 255, 0.04);
  color: #cbd5e1;
}

body[data-pc-theme='dark'] .ipcs-social-login:hover {
  background: rgba(255, 255, 255, 0.08);
}

body[data-pc-theme='dark'] .ipcs-social-toggle {
  color: #748892;
  border-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-login-register-row {
  border-top-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-login-register-link {
  color: #8cc2ff;
}

body[data-pc-theme='dark'] .ipcs-quick-step,
body[data-pc-theme='dark'] .ipcs-product-feature-card {
  background: #1b232d;
  border-color: #303f50;
  color: #cbd5e1;
}

body[data-pc-theme='dark'] .ipcs-sidebar-card {
  background:
    linear-gradient(180deg, rgba(26, 36, 48, 0.96), rgba(21, 30, 40, 0.98)),
    radial-gradient(circle at top right, rgba(182, 146, 88, 0.08), transparent 28%);
  border-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-page-head {
  background:
    linear-gradient(135deg, rgba(26, 36, 48, 0.98), rgba(21, 30, 40, 0.98)),
    radial-gradient(circle at top right, rgba(182, 146, 88, 0.08), transparent 28%);
  border-color: #303f50;
}

body[data-pc-theme='dark'] .ipcs-credit-pill {
  background: rgba(59, 130, 246, 0.12);
  color: #93c5fd;
  border-color: rgba(59, 130, 246, 0.24);
}

body[data-pc-theme='dark'] .ipcs-module-expiry-pill {
  background: rgba(45, 212, 191, 0.14);
  color: #5eead4;
  border-color: rgba(45, 212, 191, 0.28);
}

body[data-pc-theme='dark'] .ipcs-topbar-credit-pill {
  background: rgba(59, 130, 246, 0.12);
  color: #93c5fd;
  border-color: rgba(59, 130, 246, 0.24);
}

/* ── Dark mode: payment method brand colors ── */

/* ── Dark mode: price strikethrough ── */

/* ── Dark mode: configurator ── */

body[data-pc-theme='dark'] .ipcs-summary-row { color: #748892; }
body[data-pc-theme='dark'] .ipcs-summary-row strong { color: #edf3f7; }

body[data-pc-theme='dark'] .ipcs-section-head h4 { color: #edf3f7; }
body[data-pc-theme='dark'] .ipcs-section-head + p.text-muted { color: #748892 !important; }

/* ── Dark mode: installment options ── */

@media (max-width: 991px) {
  .ipcs-learning-item {
    grid-template-columns: 1fr;
    align-items: flex-start;
  }

  .ipcs-learning-item__icon {
    width: 2.25rem;
    height: 2.25rem;
  }

  .ipcs-learning-card__head {
    align-items: flex-start;
  }

  .ipcs-product-feature-grid,
  .ipcs-accent-options {
    grid-template-columns: 1fr;
  }

  .ipcs-ws-page {
    padding: 24px 16px;
    gap: 20px;
  }

  .ipcs-ws-grid {
    grid-template-columns: 1fr;
  }

  

  

  
}

/* ═══════ Dark mode: catalog page ═══════ */

/* ═══════ 訂購紀錄：清單 + 右側詳細 ═══════ */

/* ═══════ 購買流程模擬 Modal ═══════ */
.ipcs-buy-flow-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid #d8e0e7;
  border-radius: 10px;
  background: #F4F7FA;
}
.ipcs-buy-flow-summary--success {
  border-color: rgba(16, 185, 129, 0.32);
  background: rgba(16, 185, 129, 0.06);
}
.ipcs-buy-flow-summary strong {
  font-size: 1.05rem;
}

.ipcs-buy-flow-spinner {
  display: inline-flex;
  gap: 6px;
}
.ipcs-buy-flow-spinner div {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #04A9F5;
  animation: ipcs-buy-flow-bounce 1.2s ease-in-out infinite;
}
.ipcs-buy-flow-spinner div:nth-child(2) { animation-delay: 0.2s; }
.ipcs-buy-flow-spinner div:nth-child(3) { animation-delay: 0.4s; }
@keyframes ipcs-buy-flow-bounce {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
  40% { transform: scale(1); opacity: 1; }
}

body[data-pc-theme='dark'] .ipcs-buy-flow-summary {
  background: #1b232d;
  border-color: #303f50;
  color: #e2e8f0;
}
body[data-pc-theme='dark'] .ipcs-buy-flow-summary--success {
  background: rgba(16, 185, 129, 0.1);
  border-color: rgba(16, 185, 129, 0.4);
}

/* ═══════ Sidebar 訂購資訊 accordion（企業版超管） ═══════ */
.ipcs-sidebar-accordion {
  margin: 6px 12px 12px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  background: #ffffff;
  overflow: hidden;
}
.ipcs-sidebar-accordion__head {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 10px;
  padding: 10px 14px;
  background: transparent;
  border: none;
  text-align: left;
  font-weight: 600;
  color: inherit;
  cursor: pointer;
}
.ipcs-sidebar-accordion__head .pc-micon i {
  font-size: 1.1rem;
}
.ipcs-sidebar-accordion__head:hover {
  background: rgba(4, 169, 245, 0.06);
}
.ipcs-sidebar-accordion__label {
  flex-grow: 1;
}
.ipcs-sidebar-accordion__chevron {
  transition: transform 0.18s;
  font-size: 0.85rem;
  color: #64748b;
}
.ipcs-sidebar-accordion__head[aria-expanded="true"] .ipcs-sidebar-accordion__chevron {
  transform: rotate(180deg);
}
.ipcs-sidebar-accordion__body {
  padding: 12px 14px 14px;
  border-top: 1px solid #e2e8f0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ipcs-sidebar-accordion__row {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

body[data-pc-theme='dark'] .ipcs-sidebar-accordion {
  background: #1b232d;
  border-color: #303f50;
  color: #e2e8f0;
}
body[data-pc-theme='dark'] .ipcs-sidebar-accordion__head:hover {
  background: rgba(56, 189, 248, 0.08);
}
body[data-pc-theme='dark'] .ipcs-sidebar-accordion__body {
  border-top-color: #303f50;
}
body[data-pc-theme='dark'] .ipcs-sidebar-accordion__chevron {
  color: #748892;
}

/* ═══════ 加購點數 Modal 選項 ═══════ */
.ipcs-credit-topup-option {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 14px 16px;
  border: 1px solid #d8e0e7;
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.18s, background-color 0.18s;
}
.ipcs-credit-topup-option:hover {
  border-color: rgba(4, 169, 245, 0.4);
}
.ipcs-credit-topup-option:has(input:checked) {
  border-color: #04A9F5;
  background: rgba(4, 169, 245, 0.06);
}
.ipcs-credit-topup-option__price {
  font-weight: 600;
  font-size: 1.05rem;
  color: #04A9F5;
}

body[data-pc-theme='dark'] .ipcs-credit-topup-option {
  background: #1b232d;
  border-color: #303f50;
  color: #e2e8f0;
}
body[data-pc-theme='dark'] .ipcs-credit-topup-option:has(input:checked) {
  border-color: #38bdf8;
  background: rgba(56, 189, 248, 0.1);
}

/* ═══════ Backoffice Handoff 模擬畫面 ═══════ */
.ipcs-backoffice-stages {
  display: grid;
  gap: 12px;
  max-width: 480px;
  margin: 0 auto;
}
.ipcs-backoffice-stage {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border: 1px solid #d8e0e7;
  border-radius: 10px;
  background: #F4F7FA;
  text-align: left;
  transition: border-color 0.25s, background-color 0.25s;
}
.ipcs-backoffice-stage__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(4, 169, 245, 0.12);
  color: #04A9F5;
  font-size: 1.3rem;
}
.ipcs-backoffice-stage__icon .ph-spinner-gap {
  animation: ipcs-spin 1s linear infinite;
}
.ipcs-backoffice-stage.is-complete {
  border-color: rgba(16, 185, 129, 0.32);
  background: rgba(16, 185, 129, 0.06);
}
.ipcs-backoffice-stage.is-complete .ipcs-backoffice-stage__icon {
  background: rgba(16, 185, 129, 0.14);
  color: #10b981;
}
.ipcs-backoffice-stage.is-complete .ipcs-backoffice-stage__icon i {
  animation: none;
}

@keyframes ipcs-spin {
  to { transform: rotate(360deg); }
}

body[data-pc-theme='dark'] .ipcs-backoffice-stage {
  background: #1b232d;
  border-color: #303f50;
  color: #e2e8f0;
}
body[data-pc-theme='dark'] .ipcs-backoffice-stage.is-complete {
  background: rgba(16, 185, 129, 0.1);
  border-color: rgba(16, 185, 129, 0.45);
}

/* ═════ Login Mode Switch (角色 showcase ↔ SysAdmin) ═════ */
.ipcs-login-mode-switch {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  padding: 4px;
  background: #f0f3f9;
  border-radius: 10px;
  margin-bottom: 20px;
}
.ipcs-login-mode-switch__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 12px;
  border-radius: 7px;
  border: none;
  background: transparent;
  color: var(--bs-secondary-color, #5a6b7a);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.ipcs-login-mode-switch__btn i { font-size: 16px; }
.ipcs-login-mode-switch__btn:hover {
  background: rgba(4, 169, 245, 0.08);
  color: #04A9F5;
}
.ipcs-login-mode-switch__btn.is-active {
  background: var(--bs-card-bg, #ffffff);
  color: var(--bs-heading-color, #29344A);
  font-weight: 600;
  box-shadow: 0 2px 4px rgba(41, 52, 74, 0.08);
  cursor: default;
}
.ipcs-login-mode-switch__btn.is-active:hover {
  background: var(--bs-card-bg, #ffffff);
  color: var(--bs-heading-color, #29344A);
}

/* ═════ Workspaces 卡片：系統管理平台 variant ═════ */
/* 用深色底 + 黃色強調,明顯區隔於一般白底工作區卡片。
   舊版淺黃底 (#fffbeb) 跟 yellow showcase tag / badge 對比度過低,改成深底版本 */
.ipcs-ws-card--sysadmin {
  border: 1px solid #d39810;
  background: linear-gradient(135deg, #2D2418 0%, #1A1D2B 100%);
  color: #fff;
}
@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card--sysadmin:hover {
    border-color: #F4C22B;
    box-shadow: 0 12px 32px rgba(244, 194, 43, 0.32);
  }
}
.ipcs-ws-card--sysadmin .ipcs-avatar {
  width: 48px; height: 48px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 22px; border-radius: 12px;
  background: rgba(244, 194, 43, 0.18);
  color: #F4C22B;
  border: 1px solid rgba(244, 194, 43, 0.4);
}
/* 深底卡片需要 override 所有預設淺色字 */
.ipcs-ws-card--sysadmin .ipcs-ws-card__showcase-tag {
  background: rgba(244, 194, 43, 0.18);
  color: #FFD662;
  border-color: rgba(244, 194, 43, 0.5);
}
.ipcs-ws-card--sysadmin .ipcs-ws-card__name strong { color: #fff; }
.ipcs-ws-card--sysadmin .ipcs-ws-card__type {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.ipcs-ws-card--sysadmin .ipcs-ws-card__desc { color: rgba(255, 255, 255, 0.78); }
.ipcs-ws-card--sysadmin .ipcs-ws-card__status { color: rgba(255, 255, 255, 0.6); }
.ipcs-ws-card--sysadmin .ipcs-ws-card__enter { color: #F4C22B; }
.ipcs-ws-card--sysadmin .ipcs-ws-card__footer { border-top-color: rgba(255, 255, 255, 0.14); }

/* ═════ 角色測試按鈕 — 暫時用，未來會拿掉 ═════ */

/* ═════ 測試快捷登入區 (暫時測試用,正式上線移除) ═════ */

/* ═════ 圖示選擇器 grid ═════ */
.ipcs-icon-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
  gap: 8px;
}
.ipcs-icon-picker-cell {
  background: var(--bs-card-bg, #ffffff);
  border: 1px solid var(--bs-border-color, #DBE0E5);
  border-radius: 8px;
  padding: 12px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  transition: transform 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.ipcs-icon-picker-cell:hover {
  transform: translateY(-2px);
  border-color: #04A9F5;
  box-shadow: 0 4px 12px rgba(4, 169, 245, 0.15);
}
.ipcs-icon-picker-cell i { font-size: 28px; color: var(--bs-heading-color, #29344A); }
.ipcs-icon-picker-cell small { font-size: 10.5px; color: var(--bs-secondary-color, #5a6b7a); line-height: 1.2; word-break: break-all; }

/* ═════ 底板選擇器 grid ═════ */
.ipcs-backplate-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}
.ipcs-backplate-picker-cell {
  background: var(--bs-card-bg, #ffffff);
  border: 1px solid var(--bs-border-color, #DBE0E5);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  transition: transform 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.ipcs-backplate-picker-cell:hover {
  transform: translateY(-2px);
  border-color: #04A9F5;
  box-shadow: 0 4px 12px rgba(4, 169, 245, 0.15);
}
.ipcs-backplate-picker-cell strong { font-size: 13.5px; color: var(--bs-heading-color, #29344A); margin-top: 4px; }
.ipcs-backplate-picker-cell small { font-size: 11px; }
.ipcs-backplate-picker-cell .ipcs-module-symbol { width: 48px !important; height: 48px !important; }
.ipcs-backplate-picker-cell .ipcs-module-symbol i { font-size: 22px; }

/* ═════ Inline 編輯模式 (CMS edit on /modules/{slug}) ═════ */
.ipcs-inline-edit-bar {
  position: sticky; top: 0; z-index: 150;
  background: var(--bs-warning-bg-subtle, #FFFBEB);
  border-bottom: 2px solid var(--bs-warning, #F4C22B);
  box-shadow: 0 2px 8px rgba(244, 194, 43, 0.2);
}
.ipcs-inline-edit-bar__inner {
  max-width: 1280px; margin: 0 auto;
  padding: 10px 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.ipcs-cms-remove {
  position: absolute; top: 8px; right: 8px;
  width: 26px; height: 26px;
  background: #F44236; color: #fff;
  border: none; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; cursor: pointer;
  opacity: 0.92;
  /* 提升到 Bootstrap accordion-button(z-index:3) 之上,讓 FAQ 內 X 也可點 */
  z-index: 10;
  box-shadow: 0 1px 4px rgba(244,66,54,0.35);
  transition: opacity 0.12s, transform 0.12s;
}
.ipcs-cms-remove:hover { opacity: 1; transform: scale(1.1); }
.ipcs-cms-remove--inline {
  position: static; margin-left: auto;
  width: 28px; height: 28px;
}

/* ═════ 編輯模式視覺
   設計目標:可編輯欄位點下去 contenteditable 後,絕對不能造成 layout shift
   做法:
   - 一律用 outline + background (絕不動 padding/border/margin)
   - 移除瀏覽器預設 contenteditable focus 黑框
   - outline 永遠存在,只切換 color (不切換 width,避免 sub-pixel 微縮)
   ═════ */
body.cms-edit-mode [data-cms-field] {
  outline: 1.5px dashed rgba(4, 169, 245, 0.4);
  outline-offset: 4px;
  border-radius: 4px;
  cursor: text;
  transition: outline-color 0.15s, background-color 0.15s;
}
body.cms-edit-mode [data-cms-field]:hover {
  outline-color: rgba(4, 169, 245, 0.65);
  background-color: rgba(4, 169, 245, 0.04);
}
body.cms-edit-mode [data-cms-field]:focus,
body.cms-edit-mode [data-cms-field]:focus-visible {
  outline-color: #04A9F5;
  background-color: rgba(4, 169, 245, 0.08);
}
/* 關鍵:重置瀏覽器預設 contenteditable 焦點黑框與內距 */
[contenteditable="true"]:focus {
  outline: none;
}
body.cms-edit-mode [contenteditable="true"] {
  -webkit-user-modify: read-write-plaintext-only;
  word-break: break-word;
  white-space: pre-wrap;
}
body.cms-edit-mode [data-cms-row] {
  position: relative;
}
body.cms-edit-mode [data-cms-row]:hover {
  outline: 1.5px dashed rgba(4, 169, 245, 0.35);
  outline-offset: 6px;
  border-radius: 8px;
}

/* ═════ SysAdmin 模組卡 (Modules — mirror 使用者卡片) ═════
   2026-06-23 從 Views/SysAdmin/Modules.cshtml inline <style> 搬入,
   符合「自訂 CSS 一律寫 ipcs-showcase.css」規則 */

/* L1 產品大卡 (跟 /Ipcs/Modules L1 一致) */
@media (hover: hover) and (pointer: fine) {
  .ipcs-product-l1-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 28px rgba(27,46,94,0.08);
    border-color: var(--bs-primary, #04A9F5) !important;
  }
}
body.sys-edit-mode [data-cms-product-field][contenteditable="true"] {
  outline: 1.5px dashed rgba(4, 169, 245, 0.4);
  outline-offset: 4px;
  border-radius: 4px;
  cursor: text;
  transition: outline-color 0.15s, background-color 0.15s;
}
body.sys-edit-mode [data-cms-product-field][contenteditable="true"]:hover {
  outline-color: rgba(4,169,245,0.65);
  background-color: rgba(4,169,245,0.04);
}
body.sys-edit-mode [data-cms-product-field][contenteditable="true"]:focus {
  outline-color: #04A9F5;
  background-color: rgba(4,169,245,0.08);
}

.ipcs-sys-mod-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
  margin-bottom: 12px;
}
.ipcs-sys-mod-card {
  position: relative;
  background: var(--bs-card-bg, #FFFFFF);
  border: 1px solid var(--bs-border-color, #DBE0E5);
  border-radius: 14px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: transform 0.2s, box-shadow 0.2s, opacity 0.4s;
}
.ipcs-sys-mod-card:hover {
  box-shadow: 0 10px 28px rgba(27,46,94,0.08);
  transform: translateY(-2px);
}
.ipcs-sys-mod-card .min-width-0 { min-width: 0; }
.ipcs-sys-mod-card--draft {
  background: var(--bs-tertiary-bg, #F4F7FA);
}
.ipcs-sys-mod-card__topright {
  position: absolute;
  top: 12px; right: 12px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  background: var(--bs-tertiary-bg, #F4F7FA);
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(41,52,74,0.08);
  z-index: 5;
}
.ipcs-sys-mod-card__topright .form-check-input { cursor: pointer; }
.ipcs-sys-mod-card__publish-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  cursor: pointer;
}
.ipcs-sys-mod-card__publish-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--bs-secondary-color, #5a6b7a);
  user-select: none;
}
.ipcs-sys-mod-card__identity {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding-right: 100px;
}
.ipcs-sys-mod-card__identity .ipcs-module-symbol {
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  font-size: 22px;
}
.ipcs-sys-mod-card__title-block { flex: 1; min-width: 0; }
.ipcs-sys-mod-card__badges {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.ipcs-sys-mod-card__name {
  font-size: 17px;
  font-weight: 700;
  color: var(--bs-heading-color, #29344A);
  margin: 4px 0 4px;
  line-height: 1.3;
}
.ipcs-sys-mod-card__tagline {
  font-size: 13px;
  color: var(--bs-secondary-color, #5a6b7a);
  line-height: 1.5;
  margin: 0;
}
.ipcs-sys-mod-card__actions {
  display: flex;
  gap: 6px;
  margin-top: auto;
  flex-wrap: wrap;
}
.ipcs-sys-mod-card__actions .btn {
  flex: 1 1 calc(33% - 6px);
  min-width: 90px;
  font-size: 12.5px;
  padding: 6px 8px;
  white-space: nowrap;
}
.ipcs-sys-mod-card__sub-links {
  display: flex;
  gap: 12px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed var(--bs-border-color, #DBE0E5);
  font-size: 11px;
  flex-wrap: wrap;
}
.ipcs-sys-mod-card__sub-links a {
  color: var(--bs-secondary-color, #5a6b7a);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: color 0.12s;
}
.ipcs-sys-mod-card__sub-links a:hover {
  color: #04A9F5;
}

/* 編輯模式視覺 */
body.sys-edit-mode .ipcs-sys-mod-card__name[contenteditable="true"],
body.sys-edit-mode .ipcs-sys-mod-card__tagline[contenteditable="true"] {
  outline: 1.5px dashed rgba(4, 169, 245, 0.4);
  outline-offset: 4px;
  border-radius: 4px;
  cursor: text;
  transition: outline-color 0.15s, background-color 0.15s;
}
body.sys-edit-mode .ipcs-sys-mod-card__name[contenteditable="true"]:hover,
body.sys-edit-mode .ipcs-sys-mod-card__tagline[contenteditable="true"]:hover {
  outline-color: rgba(4,169,245,0.65);
  background-color: rgba(4,169,245,0.04);
}
body.sys-edit-mode .ipcs-sys-mod-card__name[contenteditable="true"]:focus,
body.sys-edit-mode .ipcs-sys-mod-card__tagline[contenteditable="true"]:focus {
  outline-color: #04A9F5;
  background-color: rgba(4,169,245,0.08);
}

@keyframes ipcs-sys-card-publish-flash {
  0% { background: rgba(29,233,182,0.25); transform: scale(1.03); }
  100% { background: var(--bs-card-bg); transform: scale(1); }
}
.ipcs-sys-mod-card--publishing { animation: ipcs-sys-card-publish-flash 0.6s ease-out; }
.ipcs-sys-mod-card--saved { animation: ipcs-sys-card-publish-flash 0.5s ease-out; }

.ipcs-sys-mod-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 32px;
  color: var(--bs-secondary-color, #5a6b7a);
  border: 1px dashed var(--bs-border-color);
  border-radius: 12px;
  background: var(--bs-tertiary-bg);
}
.ipcs-sys-mod-empty i { font-size: 32px; color: #04A9F5; }
.ipcs-sys-mod-empty p { font-size: 14px; font-weight: 600; }
.ipcs-sys-mod-empty small { font-size: 12px; }

/* ═════ SysAdmin Toast (storage confirm) ═════ */
.ipcs-sys-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9999;
  background: var(--bs-success, #1DE9B6);
  color: var(--bs-body-bg, #fff);
  padding: 12px 18px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  box-shadow: 0 8px 24px rgba(29, 233, 182, 0.3);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.25s, transform 0.25s;
  display: flex;
  align-items: center;
}
.ipcs-sys-toast.show {
  opacity: 1;
  transform: translateY(0);
}

/* ═══════ /Ipcs/MyProfile — 帳號資訊純顯示（非表單） ═══════ */
.ipcs-profile-info dt {
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
}
.ipcs-profile-info dd {
  font-size: 0.95rem;
  color: #29344A;
  word-break: break-word;
}
.ipcs-profile-uid {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
  padding: 4px 8px;
  border-radius: 6px;
  background: #F4F7FA;
  color: #29344A;
  border: 1px solid #DBE0E5;
}

body[data-pc-theme='dark'] .ipcs-profile-info dd { color: #edf3f7; }
body[data-pc-theme='dark'] .ipcs-profile-uid {
  background: #1b232d;
  color: #e2e8f0;
  border-color: #303f50;
}

/* ═══════ Login social brand colors (官方品牌指南) ═══════ */
/* Google: 白底 + 灰邊 + 深字 + 彩色 logo (官方規範 logo 不可改色) */
.ipcs-social-login--google {
  background: #FFFFFF;
  color: #3C4043;
  border-color: #DADCE0;
}
.ipcs-social-login--google:hover {
  background: #F8F9FA;
  border-color: #D2D5D9;
}

/* LINE: 官方綠 #06C755 + 白字 + 白 logo */
.ipcs-social-login--line {
  background: #06C755;
  color: #FFFFFF;
  border-color: #06C755;
}
.ipcs-social-login--line:hover {
  background: #05B14C;
  border-color: #05B14C;
  color: #FFFFFF;
}

/* Apple: 純黑 + 白字 + 白 logo */
.ipcs-social-login--apple {
  background: #000000;
  color: #FFFFFF;
  border-color: #000000;
}
.ipcs-social-login--apple:hover {
  background: #1a1a1a;
  border-color: #1a1a1a;
  color: #FFFFFF;
}

/* Facebook: 官方藍 #1877F2 + 白字 + 白 logo */
.ipcs-social-login--facebook {
  background: #1877F2;
  color: #FFFFFF;
  border-color: #1877F2;
}
.ipcs-social-login--facebook:hover {
  background: #146FE0;
  border-color: #146FE0;
  color: #FFFFFF;
}

/* Dark mode 微調 — 品牌色不變 (品牌識別需保留),只調 Google 的白底 hover */
body[data-pc-theme='dark'] .ipcs-social-login--google {
  background: #F1F3F4;
  color: #1F1F1F;
}
body[data-pc-theme='dark'] .ipcs-social-login--google:hover {
  background: #E8EAED;
}

/* 深色模式下,通用 .ipcs-social-login 暗底覆寫 (specificity 0,2,1) 會壓過品牌 modifier (0,1,0),
   害 LINE/Apple/Facebook 全變同一塊灰底 → 沒有品牌色。這裡用同特異度 + 較後宣告搶回品牌色 (2026-06-24) */
body[data-pc-theme='dark'] .ipcs-social-login--line {
  background: #06C755;
  color: #FFFFFF;
  border-color: #06C755;
}
body[data-pc-theme='dark'] .ipcs-social-login--line:hover {
  background: #05B14C;
  border-color: #05B14C;
}

body[data-pc-theme='dark'] .ipcs-social-login--facebook {
  background: #1877F2;
  color: #FFFFFF;
  border-color: #1877F2;
}
body[data-pc-theme='dark'] .ipcs-social-login--facebook:hover {
  background: #146FE0;
  border-color: #146FE0;
}

/* Apple 官方規範:深色背景改用白底黑字版 (黑底會跟深色卡片融在一起變隱形) */
body[data-pc-theme='dark'] .ipcs-social-login--apple {
  background: #FFFFFF;
  color: #000000;
  border-color: #FFFFFF;
}
body[data-pc-theme='dark'] .ipcs-social-login--apple:hover {
  background: #F1F3F4;
  border-color: #F1F3F4;
}

/* ═══════ 公司頭像 — 6 色 accent + 支援 icon / 文字 (WorkspaceBrand 自訂) ═══════ */
.ipcs-ws-avatar {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  letter-spacing: 0.5px;
  border-radius: 12px;
  transition: transform 0.18s ease;
}
.ipcs-ws-avatar i { font-size: 1.4em; }
/* 公司 API icon 疊圖 — 吃 organization.iconUrl。
   ── 🔴 2026-09-21:`object-fit` 從 cover 改成 contain ────────────────────────────
   IPCS.Auth `dev-v1.0.94` 起,`iconUrl` **不再保證是正方形**:他們原本在上傳當下就置中裁方,
   使用者反映公司 logo 多是橫式、裁方會把字截掉(而上傳者當下看不到會被裁成什麼樣),
   所以改成維持原比例、只把最長邊縮到 256px。

   ⚠️ **API 契約完全沒變**(還是一個網址字串),變的是那個網址背後那張圖的形狀 ——
   所以我方不會有任何錯誤訊號,`cover` 只會安靜地把 logo 左右切掉,
   而使用者的感受與 AUTH 剛修掉的那個問題一模一樣。

   ⚠️ **既有的 icon 仍然是方的**(資料庫裡存的就是當初裁好的方圖,原圖沒保留)——
   拿既有資料測**看不出任何差別**,很容易誤以為這件事沒發生。要驗就找一個組織
   重新上傳一張**明顯是橫的、有字的** logo。

   容器維持 52×52(卡片排版靠它),圖片改成在框內完整顯示;
   `inset:0` + `contain` 會自動置中留白,不需要額外的對齊規則。 */
.ipcs-ws-avatar__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: inherit;
}

/* sidebar / SwitchWorkspace 卡片 / WorkspaceSettings 預覽都用同一組 size — 52x52 圓角方塊 (非橢圓) */
.ipcs-ws-sidebar-avatar { width: 52px; height: 52px; font-size: 1.4rem; flex: 0 0 auto; }

/* SelectOrganization icon-only enter CTA (使用者 2026-06-02:不要「進入」文字,只留 icon) */
.ipcs-ws-card__enter-icon {
  color: rgba(255, 255, 255, 0.85);
  font-size: 1.1rem;
  transition: transform 0.18s ease;
}
@media (hover: hover) and (pointer: fine) {
  .ipcs-ws-card:hover .ipcs-ws-card__enter-icon {
    transform: translateX(3px);
  }
}

/* ═══════ Form-wrapped .ipcs-ws-card (button submit instead of anchor) ═══════ */
/* SwitchWorkspace / SelectOrganization 把卡片包在 form 內,改 button submit;
   讓 form 對 grid layout 透明,button 完全繼承 .ipcs-ws-card 樣式 */
.ipcs-ws-card-form {
  display: contents;
}
.ipcs-ws-card--button {
  width: 100%;
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* ═══════ Brand accent — topbar 公司 avatar (色點/sidebar 卡頂彩條已移除) ═══════ */
/* body 透過 inline style 注入 --ipcs-brand-accent;6 色循環,沒設 fallback #04A9F5 藍 */

/* topbar 工作區列的公司 avatar — 取代原 ph-buildings icon,可由 WorkspaceSettings 自訂 */
.ipcs-topbar-ws-avatar {
  width: 34px;
  height: 34px;
  font-size: 0.95rem;
  border-radius: 9px;
  flex: 0 0 auto;
}

/* ── topbar 公司 avatar:**有後台圖片時**改成「固定高度、寬度依比例自適應」 ──────────
   (使用者 2026-09-21:「不需要有公司字首,可以直接是 AUTH 傳來的圖片就好」
    「不要是正方形的,可以依照圖片大小顯示,但可以限制高度,可以是自適應的寬度」)

   ⚠️ 只改 topbar 這一顆。`.ipcs-ws-avatar__img` 是共用 class,選公司卡片 / 切換工作區
   (`WorkspaceCard.tsx`)也在用 —— 所以新規則全部掛在 `--image` 修飾詞底下,不動共用那層。

   改之前的問題:容器是 34×34 方塊、圖片 `position:absolute; inset:0; object-fit:cover`
   ⇒ **寬的 logo 會被裁掉左右兩側**,而且底下永遠墊著公司字首(透明 PNG 會透出來)。 */
.ipcs-topbar-ws-avatar--image {
  width: auto;          /* 寬度交給圖片 */
  overflow: visible;
  /* 底色與圓角都拿掉:使用者要的是「直接是那張圖」,而有底色的圓角方塊會讓透明 logo
     看起來像被塞進一個色塊裡。accent class 仍然掛著(server 算的、測試也釘著),
     只是在這個修飾詞底下不生效。 */
  background: transparent;
  border-radius: 0;
}

.ipcs-topbar-ws-avatar--image .ipcs-ws-avatar__img {
  position: static;     /* 不再絕對定位覆蓋 —— 由它自己撐出容器寬度 */
  inset: auto;
  height: 34px;         /* 唯一被限制的維度,與原本的方塊等高,不會改變 topbar 行高 */
  width: auto;          /* 依圖片原始比例 */
  /* ⚠️ 上限是**防護**不是設計:這張圖來自後台(organization.iconUrl),
     若有人放一張很寬的橫幅,topbar 在手機寬度會被推爆。34px 高 × 160px ≈ 4.7:1,
     一般公司 logo 不會超過。**要放寬改這一行就好。** */
  max-width: 160px;
  object-fit: contain;  /* 不是 cover —— contain 才不會裁切 */
  border-radius: 0;
}

.ipcs-ws-avatar--primary { background: rgba(4, 169, 245, 0.12); color: #04A9F5; }
.ipcs-ws-avatar--success { background: rgba(29, 233, 182, 0.18); color: #13b674; }
.ipcs-ws-avatar--warning { background: rgba(244, 194, 43, 0.20); color: #d39810; }
.ipcs-ws-avatar--danger  { background: rgba(244, 66, 54, 0.14);  color: #d63729; }
.ipcs-ws-avatar--info    { background: rgba(62, 191, 234, 0.16); color: #1e8fc4; }
.ipcs-ws-avatar--dark    { background: rgba(41, 52, 74, 0.12);   color: #29344A; }

body[data-pc-theme='dark'] .ipcs-ws-avatar--primary { background: rgba(4, 169, 245, 0.2); color: #5dc3f8; }
body[data-pc-theme='dark'] .ipcs-ws-avatar--success { background: rgba(29, 233, 182, 0.22); color: #4ed8a8; }
body[data-pc-theme='dark'] .ipcs-ws-avatar--warning { background: rgba(244, 194, 43, 0.28); color: #f0b830; }
body[data-pc-theme='dark'] .ipcs-ws-avatar--danger  { background: rgba(244, 66, 54, 0.2);  color: #ee7a72; }
body[data-pc-theme='dark'] .ipcs-ws-avatar--info    { background: rgba(62, 191, 234, 0.22); color: #6fc7e9; }
body[data-pc-theme='dark'] .ipcs-ws-avatar--dark    { background: rgba(255, 255, 255, 0.08); color: #d6dee5; }

/* ═══════ SweetAlert2 霧化背景 — 套到關鍵 modal (e.g. 登入逾時) ═══════ */
/* 用 customClass: { container: 'ipcs-modal-backdrop-blur' } 啟用 */
.swal2-container.ipcs-modal-backdrop-blur {
  background: rgba(15, 23, 42, 0.55) !important;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.swal2-container.ipcs-modal-backdrop-blur .swal2-popup {
  box-shadow: 0 24px 64px rgba(15, 23, 42, 0.35);
}

/* lightbox 圖片放大 — 限最大尺寸不超過 viewport,點外面 / X / ESC 關閉 */
.ipcs-lightbox-image {
  max-width: min(90vw, 1600px);
  max-height: 82vh;
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
  object-fit: contain;
}
/* hint cursor */
[data-ipcs-lightbox] { cursor: zoom-in; }

/* ═══════════════════════════════════════════════════════════════════
   SSO Callback (Receiver 端落地頁) — 視覺對齊訂單 / 模型管理系統
   (使用者 2026-06-05:同一套 Light Able 模板的子系統應有一致 SSO UX)
   prefix `ipcs-sso-` 避免汙染模板;tokens 對齊模板 (12px radius / shadow)
   ═══════════════════════════════════════════════════════════════════ */

/* 處理中卡片 — 跟一般 .card 同 token,只給 max-width 限框 */
.ipcs-sso-card {
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}

/* 圓圈 spinner — 跟訂單系統一致 (取代原 phosphor ph-spinner-gap)
   用 currentColor / CSS variables 對齊模板色彩 */
.ipcs-sso-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--bs-border-color);
  border-top-color: var(--bs-primary);
  border-radius: 50%;
  animation: ipcs-sso-spin 0.8s linear infinite;
}
@keyframes ipcs-sso-spin {
  to { transform: rotate(360deg); }
}

/* 失敗卡片 — sso-error-card pattern (icon 圓圈 + reason pill + 描述 + 動作) */
.ipcs-sso-error-card {
  max-width: 480px;
  margin: 80px auto;
  background: var(--bs-card-bg, #fff);
  border-radius: 12px;                              /* 對齊模板 --bs-card-border-radius */
  box-shadow: 0px 8px 24px rgba(27, 46, 94, 0.08); /* 對齊模板 --pc-card-box-shadow */
  padding: 32px;
  text-align: center;
}
.ipcs-sso-error-card__icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(239, 68, 68, 0.12);
  color: #dc2626;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 16px;
  font-size: 28px;
}
.ipcs-sso-error-card__title {
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--bs-heading-color, #0f172a);
  margin-bottom: 8px;
}
.ipcs-sso-error-card__reason {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--bs-tertiary-bg, #f1f5f9);
  color: var(--bs-secondary-color, #475569);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.78rem;
  margin: 8px 0;
}
.ipcs-sso-error-card__desc {
  color: var(--bs-secondary-color, #64748b);
  font-size: 0.9rem;
  line-height: 1.6;
  margin: 12px 0 20px;
}
.ipcs-sso-error-card__actions {
  display: flex;
  gap: 8px;
  justify-content: center;
}

/* ── 產品中心 L1 卡片內含模組 inline 攤開 (使用者 2026-06-24) ──
   多模組產品不再強制點進 drill-in 頁;子模組以精簡列直接呈現在卡片下方,
   用 Bootstrap collapse 預設展開可收。token 對齊模板原生 (--bs-border-color / --bs-card-border-radius)。 */
.ipcs-submodule-inline {
  border-top: 1px dashed var(--bs-border-color, #DBE0E5);
  padding-top: 14px;
}
/* 每個功能一張貼齊內容寬度的小卡 (沿用 .ipcs-pp-card),進入/了解更多/操作教學全做方塊磚。
   改 flex-wrap row + 卡片 flex:0 1 auto → 卡片只佔內容寬度、不再撐滿整欄,消除旁邊閒置空間
   (使用者 2026-06-25:功能卡只有 ~3 顆磚,旁邊空間都用不到要縮減)。 */
.ipcs-submodule-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.ipcs-submodule-card {
  align-self: flex-start;
  max-width: 100%;
  /* 使用者 2026-06-26:產品中心子功能卡不要外框,直接露出功能磚 → 更簡潔 */
  border: none;
  background: transparent;
  padding: 0;
}
body[data-pc-theme='dark'] .ipcs-submodule-card {
  border-color: transparent;
  background: transparent;
}
.ipcs-collapse-caret {
  transition: transform 0.18s ease;
}
[aria-expanded="false"] .ipcs-collapse-caret {
  transform: rotate(-90deg);
}

/* ═══ App 內(UA 含 IPCSApp)單屏登入 ═══ */
/* WebView UA 帶 IPCSApp 識別碼時(見 ipcs2.0-app platform_webview.dart 的
   applicationNameForUserAgent),_IpcsAuthLayout.cshtml 於 server-side 判斷、
   直接在 shell 加上 .ipcs-in-app class(SSR 輸出,無 JS 判斷造成的閃爍)。
   目標:登入頁在單一 viewport 內完整顯示(email + 密碼 + 圖形驗證碼 + 登入鈕 + 社群登入),
   不捲動、不顯示側邊品牌欄(App 啟動畫面已有品牌識別)。一般行動瀏覽器 / 桌面完全不受影響。
   Token 全部沿用模板既有值(card 圓角 --bs-card-border-radius / 陰影 --pc-card-box-shadow /
   preset-1 色彩皆未更動),僅壓縮間距與版面切換為單欄。 */

/* 1) Shell 鎖定單一 viewport,不捲動(100dvh 動態扣掉行動瀏覽器網址列高度,100vh 為舊瀏覽器 fallback) */
.ipcs-auth-shell.ipcs-in-app {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* 2) 側邊品牌欄隱藏(App 啟動畫面已呈現品牌識別),wrapper 改滿版高度單欄 */
.auth-main.v2.ipcs-auth-shell.ipcs-in-app .ipcs-auth-side {
  display: none;
}

.auth-main.v2.ipcs-auth-shell.ipcs-in-app .auth-wrapper {
  display: flex;
  min-height: 0;
  height: 100%;
}

/* 3) 登入表單容器:滿版置中,預設不捲動 —— 鍵盤彈出時的例外見下方 max-height media query。
   H3 修正(2026-07-08 App 模式規格):此規則原本沒有限定 .ipcs-login-form-shell,連帶鎖死了
   SelectOrganization / SwitchWorkspace / MockOrderSystem 這些同樣走 _IpcsAuthLayout、但內容
   比登入表單長很多的頁面 —— overflow:hidden + 置中 = 內容被裁切且無法捲動。
   改為只限定「登入頁本人」(.auth-form.ipcs-login-form-shell,見 Login.cshtml)才套用單屏鎖定;
   其餘走 .ipcs-auth-shell 的長內容頁改用下面的可捲動規則。 */
.auth-main.v2.ipcs-auth-shell.ipcs-in-app .auth-form.ipcs-login-form-shell {
  min-height: 0;
  height: 100%;
  width: 100%;
  padding: 12px 16px;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* 非登入頁(選擇工作區/切換工作區/模擬訂單頁等):shell/wrapper 仍鎖 100dvh(見上方 1、2 規則,
   避免 WebView 外層跟著橡皮筋回彈),但內容改用可捲動,不裁切。
   審查修正(2026-07-08 #1):base 495-503 與 workspaces 1153-1158 的 align-items:center;
   justify-content:center 會繼承進來 —— flex 置中 + overflow 捲動是引擎陷阱:內容超高時,
   被置中「推出頂端」的部分落在捲動原點之前,永遠捲不到。改 column + flex-start(捲動安全,
   比照下方 keyboard-safety media query 的做法),短內容的視覺置中改交給子元素的垂直
   margin:auto —— flexbox 規範:主軸剩餘空間為負時 auto margin 歸零,所以短內容
   (如 SelectOrganization 兩三張卡)仍居中、長內容自動從頂端開始完整可捲,兩者兼得。 */
.auth-main.v2.ipcs-auth-shell.ipcs-in-app .auth-form:not(.ipcs-login-form-shell) {
  height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
}
/* 水平置中不在此處理:.ipcs-ws-page(width:100% + margin:0 auto)與 MockOrderSystem 的
   內層 div(inline margin:0 auto)本來就自帶,column + stretch 之下照常成立。
   (MockOrder 的 inline margin 權重蓋過本規則的垂直 auto → 該頁頂端對齊,內容本就偏長,可接受。) */
.auth-main.v2.ipcs-auth-shell.ipcs-in-app .auth-form:not(.ipcs-login-form-shell) > * {
  margin-top: auto;
  margin-bottom: auto;
}

/* 4) 登入卡:蓋掉 Bootstrap my-5/mx-3 外距(Bootstrap 間距 utility 本身是 !important,
   選擇器特異度需一併提高才蓋得過);card 自身圓角 / 陰影 token 不動,只收斂外距。
   注意:.auth-form 與 .ipcs-login-form-shell 是同一個 div(見 Login.cshtml),
   選擇器不可用後代組合子分開,需寫成同元素複合類別選擇器。 */
.auth-main.v2.ipcs-auth-shell.ipcs-in-app .auth-form.ipcs-login-form-shell .card {
  margin: 0 !important;
  width: 100%;
}

.auth-main.v2.ipcs-auth-shell.ipcs-in-app .auth-form.ipcs-login-form-shell .card-body {
  padding: 20px 22px !important;
}

/* 5) 表單內距收緊 —— email / 密碼 / 驗證碼 / 登入鈕 / 社群登入在 iPhone SE 級(~667px)一屏內放得下。
   社群登入次要 provider 折疊行為沿用既有機制(Login.cshtml data-social-toggle,視窗寬 <768 就會
   收合成「更多方式」一行,App 內本就落在此寬度區間,不需另外新增 CSS/JS)。 */
.ipcs-in-app .ipcs-login-form-shell .card .mb-3 {
  margin-bottom: 0.55rem !important;
}

.ipcs-in-app .ipcs-login-form-shell .ipcs-form-label {
  margin-bottom: 4px;
}

.ipcs-in-app .ipcs-login-form-shell .ipcs-password-group .form-control,
.ipcs-in-app .ipcs-login-form-shell .ipcs-password-group .btn {
  height: 42px;
}

.ipcs-in-app .ipcs-login-form-shell .card .mt-4 {
  margin-top: 0.65rem !important;
}

.ipcs-in-app .ipcs-login-form-shell .card .saprator.my-3 {
  margin-top: 0.55rem !important;
  margin-bottom: 0.55rem !important;
}

.ipcs-in-app .ipcs-login-form-shell .ipcs-social-login-stack {
  gap: 8px;
}

.ipcs-in-app .ipcs-login-form-shell .ipcs-social-login {
  height: 42px;
}

.ipcs-in-app .ipcs-login-form-shell .ipcs-login-register-row {
  margin-top: 10px;
  padding-top: 8px;
}

/* App WebView 內高度吃緊 —— 註冊鈕收成一般按鈕高度,但不縮字(還是要讀得到)。 */
.ipcs-in-app .ipcs-login-form-shell .ipcs-login-signup {
  margin-top: 10px;
}

.ipcs-in-app .ipcs-login-form-shell .ipcs-login-signup__btn {
  height: 44px;
}

/* 6) 語言切換保留,但收邊避免壓到緊湊卡片(不影響其撐高 — 本就是 absolute 定位,不佔版面高度) */
.auth-main.v2.ipcs-auth-shell.ipcs-in-app .ipcs-auth-lang {
  top: 8px;
  right: 8px;
}

/* 7) 鍵盤安全:WebView 視口在鍵盤彈出時會變矮,此時改允許表單內層捲動,
   避免輸入框被鍵盤蓋住卻無法看到(僅限極矮視口,平常單屏情境仍不捲動)。 */
@media (max-height: 560px) {
  .auth-main.v2.ipcs-auth-shell.ipcs-in-app .auth-form {
    overflow-y: auto;
    align-items: flex-start;
    padding-top: 8px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   App 模式(body.ipcs-in-app)— 2026-07-08 App 原生化模式規格 Phase 1
   全域 App shell 基礎:登入後所有頁面(_IpcsLayout)的 App 樣式掛載點。
   規則一律綁 .ipcs-in-app class,不綁寬度斷點(iPad WebView 也要吃到這組規則)。
   Token 全部沿用模板既有值:卡圓角 --bs-card-border-radius(12px)、陰影
   --pc-card-box-shadow、主色 #04A9F5 / var(--bs-primary),不新增自訂視覺 token。
   桌面與一般行動瀏覽器完全不受影響(唯一例外是上面 §H6 的 hover media query)。
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 1) Sidebar / 漢堡 / Footer 隱藏(H2)— 職責轉移至底部 App tab ──
   不修手機瀏覽器 sidebar 開合 bug(#mobile-collapse 缺失),App 內直接繞過:
   sidebar 整個隱藏,登出/切換工作區/個人設定改走 _IpcsAppTabbar 的「設定」tab。 */
body.ipcs-in-app .pc-sidebar {
  display: none;
}
body.ipcs-in-app .ipcs-topbar-bar__left {
  display: none;
}

/* ── 2) Topbar / Container 收斂,補 sidebar 隱藏後騰出的左側偏移 ──
   桌面版 .pc-header/.pc-container 原本用 left:280px / margin-left:280px 幫 sidebar 讓位,
   sidebar 隱藏後若不補這兩條,內容會維持 280px 左邊界留白。 */
body.ipcs-in-app .pc-header {
  min-height: 56px;
  left: 0;
  padding-top: env(safe-area-inset-top);
}
body.ipcs-in-app .pc-header .header-wrapper {
  padding: 0 12px;
}
body.ipcs-in-app .ipcs-topbar-bar {
  gap: 8px;
}
body.ipcs-in-app .ipcs-topbar-current-workspace {
  padding: 0 8px;
  gap: 8px;
}
body.ipcs-in-app .ipcs-topbar-current-workspace .ipcs-topbar-pill__copy strong {
  font-size: 0.95rem;
}
/* 外觀 Customizer 齒輪 + 點數加購 pill — 皆屬購買/客製面,App 內視覺收起
   (server-side 不渲染屬第 4 節送審閘門,非 Phase 1 範圍;此處只做 CSS 收斂)。 */
body.ipcs-in-app .pct-c-btn {
  display: none !important;
}
body.ipcs-in-app .ipcs-topbar-credit-pill {
  display: none !important;
}
/* 通知 dropdown 原本 min-width:450px(style.css:21551)在 ~390px 視口出界,App 內改近全寬 sheet。 */
body.ipcs-in-app .pc-header .dropdown-notification {
  min-width: calc(100vw - 24px);
  max-width: calc(100vw - 24px);
}

body.ipcs-in-app .pc-container {
  margin-left: 0;
  top: 56px;
  min-height: calc(100vh - 56px);
  /* 底部避讓:App tab 實際高度(56px 內容 + safe-area)+ 一點呼吸間距,避免最後一塊內容被蓋住 */
  padding-bottom: calc(56px + env(safe-area-inset-bottom) + 16px);
}

/* ── 3) 頁頭壓縮(§2.4)— 桌面 hero 式頁頭吃掉首屏 ~200px+,in-app 只留標題與必要 CTA ── */
body.ipcs-in-app .ipcs-page-head {
  padding: 14px 16px;
  align-items: center;
}
body.ipcs-in-app .ipcs-page-head > div > .d-flex.align-items-center.gap-2.flex-wrap,
body.ipcs-in-app .ipcs-page-head > div > p.text-muted {
  display: none;
}
body.ipcs-in-app .ipcs-page-head h2 {
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  font-size: 1.1rem;
}

/* ── 4) 底部 App tab 導覽(_IpcsAppTabbar.cshtml,§2.1)──
   審查修正(2026-07-08 #3):雖然 partial 只在 in-app 渲染,選擇器仍補 body.ipcs-in-app
   前綴與區段內其他規則一致(defense-in-depth,防未來誤 include partial 時樣式外漏)。 */
body.ipcs-in-app .ipcs-apptab-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1030;
  display: flex;
  align-items: stretch;
  background: var(--bs-card-bg, #fff);
  border-top: 1px solid var(--bs-border-color, #d8e0e7);
  box-shadow: 0px -8px 24px rgba(27, 46, 94, 0.08);
  padding-bottom: env(safe-area-inset-bottom);
}
body.ipcs-in-app .ipcs-apptab-item {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 56px;
  padding: 6px 4px;
  color: var(--bs-secondary-color, #5a6b7a);
  text-decoration: none;
  background: transparent;
  border: none;
  font: inherit;
  transition: color 0.15s ease, transform 0.12s ease;
}
body.ipcs-in-app .ipcs-apptab-icon {
  font-size: 1.3rem;
  line-height: 1;
}
body.ipcs-in-app .ipcs-apptab-label {
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.1;
  white-space: nowrap;
}
body.ipcs-in-app .ipcs-apptab-item.is-active,
body.ipcs-in-app .ipcs-apptab-item.is-active .ipcs-apptab-icon,
body.ipcs-in-app .ipcs-apptab-settings__btn.is-active {
  color: var(--bs-primary, #04A9F5);
}
body.ipcs-in-app .ipcs-apptab-settings {
  position: relative;
  padding: 0;
}
body.ipcs-in-app .ipcs-apptab-settings__btn {
  width: 100%;
  height: 100%;
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: transparent;
  border: none;
  color: var(--bs-secondary-color, #5a6b7a);
}
body.ipcs-in-app .ipcs-apptab-settings__menu {
  min-width: 220px;
}

/* ── 5) 44px 觸控基線(§2.5)— 視覺 token(色彩/圓角/字級)不變,只加高最小命中區 ── */
body.ipcs-in-app .btn-sm,
body.ipcs-in-app .dropdown-toggle,
body.ipcs-in-app .ipcs-help-hint,
body.ipcs-in-app .ipcs-login-link,
body.ipcs-in-app .ipcs-auth-lang-toggle,
body.ipcs-in-app .ipcs-pin-btn {
  min-height: 44px;
  min-width: 44px;
}
body.ipcs-in-app .pc-head-link.dropdown-toggle,
body.ipcs-in-app .ipcs-help-hint,
body.ipcs-in-app .ipcs-pin-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ── 觸控裝置的點擊目標(2026-07-28)──
   上面那組 44px 規則原本**只在 App 殼內**(body.ipcs-in-app)生效,一般手機瀏覽器不吃。
   2026-07-28 在真實 375px 量到兩顆低於建議值:釘選鈕 32×31、「查看成員」92×31
   (iOS 44pt / Android 48dp)。用 `pointer: coarse` 精準只加在觸控裝置上 ——
   桌機滑鼠很精準,不需要為它犧牲版面密度。值沿用上面那組 44px,不另立第二套標準。 */
@media (pointer: coarse) {
  .ipcs-pin-btn,
  .ipcs-group-edit-btn,
  .ipcs-touch-target,
  .ipcs-help-hint,
  .ipcs-auth-lang-toggle {
    min-height: 44px;
    min-width: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* 磚上的「⋮」與勾選框:命中區放大但**視覺不變**(靠透明 padding,不把圓點畫大) */
  .ipcs-pp-tile-menu__toggle,
  .ipcs-pp-tile-select {
    padding: 12px;
    margin: -12px;
  }
}

/* ── 6) :active 按壓回饋(§2.5b)— 觸控裝置沒有 hover,靠這個給點擊反饋 ── */
body.ipcs-in-app .btn:active,
body.ipcs-in-app .ipcs-module-card:active,
body.ipcs-in-app .ipcs-ws-card:active,
body.ipcs-in-app .ipcs-pp-tile:active,
body.ipcs-in-app .ipcs-quicklaunch-item:active,
body.ipcs-in-app .ipcs-org-card:active,
body.ipcs-in-app .ipcs-product-l1-card:active,
body.ipcs-in-app .ipcs-apptab-item:active,
body.ipcs-in-app .ipcs-apptab-settings__btn:active {
  transform: scale(0.98);
}

/* ── 7) Modal → bottom sheet(§2.5)— 既有 ipcsAlert/ipcsConfirm(SweetAlert2)wrapper 免改 JS 全站生效 ── */
body.ipcs-in-app .modal .modal-dialog {
  margin: 0;
  min-width: 100%;
  max-width: 100%;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: auto;
}
body.ipcs-in-app .modal .modal-content {
  border-radius: var(--bs-card-border-radius, 12px) var(--bs-card-border-radius, 12px) 0 0;
  max-height: 85vh;
  overflow-y: auto;
  padding-bottom: env(safe-area-inset-bottom);
}
body.ipcs-in-app .modal.fade .modal-dialog {
  transform: translateY(100%);
}
body.ipcs-in-app .modal.show .modal-dialog {
  transform: translateY(0);
}
body.ipcs-in-app .swal2-container {
  align-items: flex-end !important;
}
body.ipcs-in-app .swal2-popup {
  border-radius: var(--bs-card-border-radius, 12px) var(--bs-card-border-radius, 12px) 0 0 !important;
  margin-bottom: 0 !important;
  width: 100% !important;
}

/* ── 8) 小字級提升(L1)— WCAG 1.4.4,App 內把明顯過小(<0.8rem)的常用文字提升 ── */
body.ipcs-in-app .ipcs-pp-tile__name,
body.ipcs-in-app .ipcs-ws-card__showcase-tag {
  font-size: 0.8rem;
}

/* ── 9) 模組中心單欄化(§Phase1 表格 (4))— 專案卡窄螢幕直排,取代 flex-wrap 自然崩落順序混亂 ── */
body.ipcs-in-app .ipcs-backoffice-project-card > .d-flex.flex-wrap {
  flex-direction: column;
  align-items: stretch;
}

/* ── 10) 減少動態效果(L7)— App 內尊重系統「減少動態效果」偏好,關閉無限循環動畫。
   維持「所有 App 樣式掛 ipcs-in-app」原則(唯一明確例外是 §H6 的 hover media query),
   一般網頁/桌面的無障礙動態偏好留待獨立需求另案處理,不在本次規格範圍內擴大。 */
@media (prefers-reduced-motion: reduce) {
  body.ipcs-in-app .ipcs-buy-flow-spinner div {
    animation: none;
    opacity: 1;
    transform: scale(1);
  }
}

/* 專案成員 modal:人多時清單自帶垂直捲軸,tag/搜尋列不隨捲動 */
.ipcs-members-scroll { max-height: 56vh; overflow-y: auto; overflow-x: hidden; }

/* 成員表格:表頭 sticky,捲動時固定在頂;角色格 = 彩色角色徽章 + ▸ + 系統灰籤 */
.ipcs-members-table thead th {
    position: sticky; top: 0; z-index: 1;
    background: var(--bs-card-bg, #fff);
    font-size: 12px; font-weight: 500; color: var(--bs-secondary-color, #5a6b7a);
}
.ipcs-role-line + .ipcs-role-line { margin-top: 6px; }
.ipcs-role-arrow { color: var(--bs-border-color, #b6c0cb); font-size: 12px; line-height: 1; }
.ipcs-sys-chip {
    display: inline-block; white-space: nowrap;
    background: var(--bs-secondary-bg, #f2f5f8);
    color: var(--bs-secondary-color, #5a6b7a);
    border: 1px solid var(--bs-border-color, #e3e8ee);
    border-radius: 6px; font-size: 12px; padding: 3px 8px;
}

/* ═══════ SPA 開機遮罩（/app React 殼專用） ═══════ */
/* 實查 2026-07-20：.loader-bg / .loader-track / .loader-fill 在 style.css、style-preset.css、
   ipcs-showcase.css 三支裡一條規則都沒有 —— Razor 版的「預載動畫」其實是看不見的空 div，
   script.js:23-28 固定 400ms 把它 remove() 純屬儀式。SPA 的空窗是真的（要等 api/v1/bootstrap），
   所以這裡補一個真的看得見的遮罩。只掛在 .ipcs-app-loader 上：Loader.cshtml 沒有這個 class，
   Razor 頁的外觀不受影響。token 對齊模板變數，不自造顏色（CLAUDE.md 模板優先原則）。 */
.ipcs-app-loader {
  position: fixed;
  inset: 0;
  z-index: 1100;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 變數定義在 :root（淺色）與 body[data-pc-theme=dark]（style-preset.css:3425-3426），
     遮罩是 body 的子節點 → 深淺色自動跟著 FOUC script 設好的屬性走，不會白底閃一下。 */
  background: var(--bs-body-bg, #fff);
}
/* 開機遮罩內容(2026-10-01 優化):字標 + 進度條;等太久的說明與出口;失敗卡 */
.ipcs-app-loader__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  padding: 0 16px;
  text-align: center;
}
.ipcs-app-loader__inner--failed {
  width: min(480px, 100%);
  gap: 1rem;
  text-align: start;
}
.ipcs-app-loader__brand .ipcs-brand-wordmark {
  height: 44px;
}
/* 字標依整頁主題切黑字 / 白字(側邊欄那組規則只管 .pc-sidebar 內) */
body[data-pc-theme='dark'] .ipcs-app-loader .ipcs-brand-wordmark--light { display: none; }
body[data-pc-theme='dark'] .ipcs-app-loader .ipcs-brand-wordmark--dark { display: block; }
.ipcs-app-loader__slow {
  animation: ipcs-app-loader-fade 0.3s ease-out;
}
@keyframes ipcs-app-loader-fade {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ipcs-app-loader__slow { animation: none; }
}

/* 「剩 N 天」徽章(2026-10-01):模板的 bg-light-danger + text-danger 小字只有 3.2:1,不到 WCAG AA,
   這裡把字加深(#b42318 on #feeceb ≈ 5.7:1);深色模式改淺字(#ffb4ab on 半透明紅 over #1b232d ≈ 7:1) */
.ipcs-badge-days-left { background-color: #feeceb; color: #b42318; }
body[data-pc-theme='dark'] .ipcs-badge-days-left { background-color: rgba(244, 66, 54, 0.2); color: #ffb4ab; }

/* 骨架屏(2026-10-01 優化):圓角對齊模板 token(徽章 6、按鈕 8、卡片圖示 12);減少動態的人不跑波浪 */
.ipcs-skeleton .placeholder { border-radius: 6px; opacity: 0.25; }
.ipcs-skeleton__title { height: 1.75rem; }
.ipcs-skeleton__avatar { width: 48px; height: 48px; border-radius: 12px !important; flex-shrink: 0; }
.ipcs-skeleton__avatar--lg { width: 64px; height: 64px; }
.ipcs-skeleton__button { height: 2rem; border-radius: 8px !important; display: inline-block; }
@media (prefers-reduced-motion: reduce) {
  .ipcs-skeleton.placeholder-wave { animation: none; -webkit-mask-image: none; mask-image: none; }
}

.ipcs-app-loader .loader-track {
  width: 180px;
  height: 4px;
  border-radius: 2px;
  background: var(--pc-active-background, #f3f5f7);
  overflow: hidden;
}
.ipcs-app-loader .loader-fill {
  width: 40%;
  height: 100%;
  border-radius: 2px;
  background: var(--bs-primary, #04a9f5);
  animation: ipcs-app-loader-slide 1.1s ease-in-out infinite;
}
@keyframes ipcs-app-loader-slide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(350%); }
}

/* customizer 面板的內容捲動：Razor 版靠 SimpleBar 包 .pct-body 產生捲軸（theme.js:74-78），
   SPA 不載 SimpleBar（F5），而 style.css:31160 的 .customizer-body 只有 height 沒有 overflow
   → 面板內容會被直接裁掉。只掛在 SPA 專用的 class 上，Razor 頁（有 SimpleBar）不受影響。 */
.ipcs-customizer-body {
  overflow-y: auto;
}

/* 外觀設定的卡片按鈕(2026-10-13,工項追蹤回報、yuuu-chih 選「字不改，卡片跟著字長高、三張一樣高」):
   模板把卡片釘在 91px,三張一排時「跟隨系統」(日文、英文更長)會斷成兩行,下面的縮圖就超出卡片。
   改成至少 91px、跟著字長高;同一排的卡片撐滿欄高 → 一樣高。範圍用模板自己的 .pct-offcanvas,
   各模組照抄這兩條就會一樣(docs/IPCS/外觀設定_給其他模組.md §4.1)。 */
.pct-offcanvas .theme-color .preset-btn {
  height: auto;
  min-height: 91px;
}
.pct-offcanvas .theme-color > [class*="col-"] > .d-grid {
  height: 100%;
}

/* ═══════════════════════════════════════════════════════════════════════
   === CMS 就地編輯（React 產品頁 + B3a 元件用；自 legacy 三頁 inline style 整併，2026-07-22）===
   來源（整批讀入、逐條 dedupe）：
     Views/Ipcs/ProductCenter.cshtml:34-167（最完整，含 progress/chip/demo/toolbar 正式 class）
     Views/Ipcs/ProductDetail.cshtml:28-74（含 .ipcs-product-description 完整版 + figure.media）
     Views/Ipcs/FunctionDetail.cshtml:28-61（同 ProductDetail 子集）
   三份是同一批「複製貼上」年代的重複 inline <style>，僅零星數值分歧（[data-cms-field] 基礎
   outline 的透明度 0.4 / 0.5、有無 min-height/transition），已合併成單一版本 —— 數值一律取自
   既有三份之一（非新設計/非新配色），下方逐條註明取捨。

   React 端沒有 legacy 的「整站單一編輯模式」body class 可掛：B3b DEC2a 是逐卡/逐頁編輯
   （ProductCard 每卡各自一份 useCmsEdit，同一頁可能同時有多張卡各自 editing 狀態），
   所以把開關從 `body.ipcs-cms-edit-mode` 改成容器級 class `.ipcs-cms-editing`
   （掛在該頁 ProductDetailContent/FunctionDetailContent 的 `.ipcs-product-page` 根節點、
   或該卡 ProductCard 的 `.ipcs-module-card` 根節點，editing===true 時加上）。
   legacy 三頁仍會載這份 ipcs-showcase.css（_IpcsLayout.cshtml:15 全站共用），為了它們還在用的
   `body.ipcs-cms-edit-mode` 開關不失效，同一條規則保留「body 版」與「container 版」兩種選擇器
   （數值逐字相同，不會疊加出視覺差異，只是多一種能命中的路徑；legacy 頁面本身的 inline
   <style> 未刪除，仍原地不動，等 B8 legacy 退場才清）。 */

.ipcs-cms-editing [data-cms-field],
body.ipcs-cms-edit-mode [data-cms-field] {
  /* 基礎樣式取 ProductCenter 版本（三份中最完整：含 min-height 防止空欄位塌陷、
     transition 讓 outline/background 切換不生硬）；outline 透明度沿用 ProductCenter 的 0.5
     （ProductDetail/FunctionDetail 兩份用 0.4，差異在複製貼上時已產生，這裡二選一，
     不影響可讀性判斷，不算重新設計）。 */
  outline: 1px dashed rgba(4, 169, 245, 0.5);
  outline-offset: 4px;
  border-radius: 4px;
  cursor: text;
  min-height: 1.2em;
  transition: outline 0.15s, background 0.15s;
}
.ipcs-cms-editing [data-cms-field]:hover,
body.ipcs-cms-edit-mode [data-cms-field]:hover {
  outline: 2px solid var(--bs-primary);
  background: rgba(var(--bs-primary-rgb), 0.04);
}
.ipcs-cms-editing [data-cms-field]:focus,
body.ipcs-cms-edit-mode [data-cms-field]:focus {
  outline: 2px solid var(--bs-primary);
  background: rgba(var(--bs-primary-rgb), 0.08);
}
.ipcs-cms-editing [data-cms-field][contenteditable=true]:empty::before,
body.ipcs-cms-edit-mode [data-cms-field][contenteditable=true]:empty::before {
  content: attr(data-placeholder);
  color: var(--bs-secondary-color);
  font-style: italic;
}

/* 縮圖可點放大 — icon/縮圖由後台 API 控制，不提供編輯，一律只能點開看大圖
   （ProductCard.tsx 的 data-ipcs-lightbox 縮圖套這個 class）。 */
.ipcs-thumb-zoomable { cursor: zoom-in; }

/* 大略介紹 (Description) — 卡片上 truncate 多行顯示（ProductCard.tsx 的 summary 欄位）。 */
.ipcs-module-description {
  color: var(--bs-secondary-color);
  font-size: 13px;
  line-height: 1.55;
  margin-top: 8px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ipcs-cms-editing .ipcs-module-description,
body.ipcs-cms-edit-mode .ipcs-module-description {
  display: block;  /* 編輯模式取消 truncate，讓 user 看到全部內容並編輯 */
}

/* 編輯模式工具列 — sticky 在頂端（CmsEditToolbar.tsx 共用，逐頁 hero 工具列與逐卡工具列都套
   同一顆 class）。legacy ProductDetail/FunctionDetail 兩頁原本沒有這條 CSS class 規則，是直接
   在該 div 寫 inline style 重複同樣效果，且背景 token 用的是 `var(--pc-header-background)`——
   該變數只在 landing.css/landing-rtl.css 定義（landing 頁專用），_IpcsLayout 沒載那兩支檔，
   ProductDetail/FunctionDetail 走 _IpcsLayout 時這個變數其實是 unset（等同透明），backdrop-filter
   模糊了但底色沒真的鋪上——是既有 legacy 小 bug。這裡採 ProductCenter 那份「真的有定義」的
   CSS class 版本當唯一正本（rgba(var(--bs-body-bg-rgb),0.97) 是隨處可用的 bootstrap token），
   三頁 + React 三處共用消費，副作用是順便把那個 legacy 透明背景 bug 合併掉了（非刻意去修，
   是 dedupe 的自然結果，legacy inline style 本身不動）。 */
.ipcs-cms-toolbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: rgba(var(--bs-body-bg-rgb), 0.97);
  backdrop-filter: blur(8px);
  margin: -16px -16px 16px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--bs-border-color);
}

/* CmsEditToolbar.tsx 非基準語系提示（!isBaseCulture 分支的 <span class="ipcs-cms-hint">）——
   legacy 對應概念是整條 `alert alert-light-info` 翻譯提示區塊（ProductCenter.cshtml:203-206），
   React 版精簡成 toolbar 內一小段行內文字，本來就吃 Bootstrap 既有的 `text-muted small`
   （元件原始 className），這裡只加一點強調感，不新增顏色 token、不做成 alert 大區塊
   （沒有動 CmsEditToolbar.tsx 邏輯的授權，維持原樣簡潔）。 */
.ipcs-cms-hint {
  font-style: italic;
}

/* CMS 內容完成度 (僅 sysadmin) — 介紹/教學/引導 是否已填寫，一眼看出進度。
   legacy ProductCenter 專用視覺語言，整批搬入備用（目前 React 頁尚未有消費者掛這幾個 class，
   B3b 沒有進度 chip 需求 DEC3a，未來若要做完成度指示可直接沿用，不必重新設計）。
   用 token (success/warning subtle bg + text-emphasis) 自動支援深色模式 + WCAG AA。 */
.ipcs-cms-progress {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
  padding: 3px 8px;
  border: 1px solid var(--bs-border-color);
  border-radius: 8px;
  background: var(--bs-body-bg);
}
.ipcs-cms-progress.is-complete {
  border-color: rgba(var(--bs-success-rgb), 0.45);
  background: rgba(var(--bs-success-rgb), 0.06);
}
.ipcs-cms-progress__count {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--bs-secondary-color);
  white-space: nowrap;
}
.ipcs-cms-progress.is-complete .ipcs-cms-progress__count { color: var(--bs-success-text-emphasis); }
.ipcs-cms-progress__count > i { font-size: 16px; }
.ipcs-cms-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 12px;
  line-height: 1;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 6px;
}
.ipcs-cms-chip > i { font-size: 11px; }
.ipcs-cms-chip.is-done {
  background: var(--bs-success-bg-subtle);
  color: var(--bs-success-text-emphasis);
}
.ipcs-cms-chip.is-todo {
  background: var(--bs-warning-bg-subtle);
  color: var(--bs-warning-text-emphasis);
  border: 1px dashed rgba(var(--bs-warning-rgb), 0.55);
}

/* sysadmin 專用：內容未填的「了解更多/操作教學」按鈕 → 虛線警示框，提示此項待補。
   一般使用者看不到(無內容時這類按鈕不渲染)，只會出現在 canEdit 視角
   （ProductCard.tsx / ProductDetailPage.tsx / ProductCenterPage.tsx 皆有消費）。 */
.ipcs-cms-empty-btn {
  border-style: dashed !important;
  border-color: rgba(var(--bs-warning-rgb), 0.6) !important;
  color: var(--bs-warning-text-emphasis) !important;
  background: transparent !important;
}
.ipcs-cms-empty-btn:hover,
.ipcs-cms-empty-btn:focus {
  background: var(--bs-warning-bg-subtle) !important;
  border-color: rgba(var(--bs-warning-rgb), 0.85) !important;
  color: var(--bs-warning-text-emphasis) !important;
}

/* 範例卡 (僅 sysadmin，ProductCenterPage.tsx 的 D6 demo 卡) — 虛線外框 + 淡底，
   和真實產品卡視覺區隔，一看就知道是示範用。 */
.ipcs-module-card--demo {
  border: 1.5px dashed rgba(var(--bs-primary-rgb), 0.5) !important;
  background: rgba(var(--bs-primary-rgb), 0.03);
}
/* 範例卡內的示範內文 — 保留換行，行距放鬆好讀。 */
.ipcs-demo-body {
  white-space: pre-wrap;
  line-height: 1.75;
  color: var(--bs-body-color);
}

/* 詳細介紹區塊 — CKEditor 產出的 HTML (段落/清單/圖片/嵌入)。取 ProductDetail 版本
   （比 FunctionDetail 那份多 figure.media / .ck-media__wrapper 定位規則，是聯集不是取捨）。
   ProductDetailPage.tsx / FunctionDetailPage.tsx 的 view 態 dangerouslySetInnerHTML 與
   edit 態 CmsRichField 都套這個 class。 */
.ipcs-product-description {
  font-size: 15px;
  line-height: 1.75;
  color: var(--bs-body-color);
}
.ipcs-product-description img { max-width: 100%; height: auto; border-radius: 8px; }
.ipcs-product-description figure { margin: 16px 0; }
.ipcs-product-description figure.media,
.ipcs-product-description .ck-media__wrapper { position: relative; }
.ipcs-product-description iframe,
.ipcs-product-description video { max-width: 100%; border-radius: 8px; }

.ipcs-cms-editing [data-cms-richtext]:not(.ck),
body.ipcs-cms-edit-mode [data-cms-richtext]:not(.ck) {
  min-height: 3em;
  cursor: text;
}
/* Classic 編輯器整塊套虛框線，提示「這裡可直接編輯」(對齊上方其他 data-cms-field 的虛線語言)。
   `.ck.ck-editor` 是 CKEditor 真的掛載後會產生的框架 class（CmsRichField.tsx 透過
   ckeditorLoader 動態載入 ClassicEditor build），選擇器不需要 React 端額外配合。 */
.ipcs-cms-editing .ck.ck-editor,
body.ipcs-cms-edit-mode .ck.ck-editor {
  outline: 1.5px dashed rgba(4, 169, 245, 0.5);
  outline-offset: 4px;
  border-radius: 4px;
}

/* ═══════════════════════════════════════════════════════════════════════
   === BuyPlan 購買精靈 —— stepper / 選購方式卡 / 方案卡 planRel(React /buy-plan 用；
   自 legacy `Views/Ipcs/BuyPlan.cshtml:600-668` 的 `@section styles` 整批搬入，2026-07-23）===
   class 名稱本身在 legacy 就已經是 `ipcs-` prefix(此頁一開始就照專案慣例命名，不是這次
   新取的名字)，數值逐字照抄，僅把 Razor 的 `@@keyframes` 轉義字元還原成一般 CSS 的
   `@keyframes`。legacy `BuyPlan.cshtml` 本身的 `@section styles` 不動（同 B3b-7 CMS 樣式
   整併的做法，legacy 頁面原地不動、等 B8 legacy 退場才清），這裡只是讓 React 端也能用
   同一份規則 —— React SPA 只載 `ipcs-showcase.css`（`frontend/index.html:25`），吃不到
   Razor `@section styles` 那段。
   消費者：`frontend/src/pages/billing/BuyPlanPage.tsx`（stepper/pick 卡）、
   `frontend/src/pages/billing/PlanCard.tsx`（`.ipcs-plan-card` 系列）。

   `.ipcs-buy-step__num` / `.ipcs-buy-step__divider` 兩顆的基礎外觀 legacy 是寫在 view
   markup 上的 inline style（並非原本 `@section styles` 那塊），這裡一併補成 class（避免
   React 元件重新寫一次 inline style），數值同樣逐字照抄 legacy inline 值，不是新設計。 */
.ipcs-buy-pick {
  display: block;
  padding: 18px 16px;
  border: 2px solid var(--bs-border-color);
  border-radius: var(--bs-card-border-radius);
  text-align: center;
  cursor: pointer;
  transition: all .18s ease;
  background: var(--bs-card-bg);
  position: relative;
  height: 100%;
}
.ipcs-buy-pick:hover { border-color: var(--bs-primary); transform: translateY(-2px); box-shadow: 0 6px 18px rgba(var(--bs-primary-rgb), .12); }
.ipcs-buy-pick.is-selected { border-color: var(--bs-primary); background: rgba(var(--bs-primary-rgb), .04); box-shadow: 0 6px 18px rgba(var(--bs-primary-rgb), .14); }
.ipcs-buy-pick.is-selected::after {
  content: "\2713"; position: absolute; top: 8px; right: 10px;
  width: 24px; height: 24px; border-radius: 50%; background: var(--bs-primary); color: #fff;
  display: flex; align-items: center; justify-content: center; font-weight: 700;
}

/* 方案卡 — 套模板 .price-card，點整張卡選取；auto-fit 網格自適應方案數量(API 增減方案不破版) */
.ipcs-plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  align-items: stretch;
}
.ipcs-plan-grid .price-card {
  margin-bottom: 0;
  height: 100%;
  cursor: pointer;
  transition: box-shadow .18s ease, transform .18s ease;
}
.ipcs-plan-grid .price-card:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(var(--bs-primary-rgb), .14); }
.ipcs-plan-card.is-selected { box-shadow: 0 0 0 2px var(--bs-primary), 0 8px 24px rgba(var(--bs-primary-rgb), .2); }
.ipcs-plan-card--contact.is-selected { box-shadow: 0 0 0 2px var(--bs-warning), 0 8px 24px rgba(var(--bs-warning-rgb), .2); }
.ipcs-plan-badge { position: absolute; top: 10px; right: 10px; z-index: 2; }
/* highlight 文字（方案卡頭一行小字）— legacy inline `style="opacity:.75;"`，逐字照搬。 */
.ipcs-plan-card__highlight { opacity: .75; }

/* 升級呈現：目前方案高亮但不可再選；低於目前方案的淡化不可選；升級方案正常可選 */
.ipcs-plan-card--current { box-shadow: 0 0 0 2px var(--bs-secondary), 0 8px 24px rgba(var(--bs-secondary-rgb), .16); pointer-events: none; }
.ipcs-plan-card--current:hover { transform: none; }
.ipcs-plan-card--lower { opacity: .5; pointer-events: none; }
.ipcs-plan-card--lower:hover { transform: none; box-shadow: none; }

/* 產品詳情「方案與價格」(Luxor Billing,2026-10-01):hover 浮起沿用工作區卡 -3px;目前方案用主色外框標出、不浮起(沒有可以按的) */
.ipcs-billing-plan { transition: box-shadow .15s ease-in-out, transform .15s ease-in-out; }
.ipcs-billing-plan:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(var(--bs-primary-rgb), .14); }
.ipcs-billing-plan.is-current { box-shadow: 0 0 0 2px var(--bs-primary), 0 8px 24px rgba(var(--bs-primary-rgb), .16); }
.ipcs-billing-plan.is-current:hover { transform: none; }
/* 試用方案卡(2026-10-06 使用者:「試用的方案也要是卡片,顏色要有特殊標示」):綠色外框,正在試用時也維持綠色 */
.ipcs-billing-plan--trial,
.ipcs-billing-plan--trial:hover,
.ipcs-billing-plan--trial.is-current { box-shadow: 0 0 0 2px var(--ipcs-trial), 0 8px 24px var(--ipcs-trial-glow); }
@media (prefers-reduced-motion: reduce) {
  .ipcs-billing-plan, .ipcs-billing-plan:hover { transition: none; transform: none; }
}

/* 產品詳情「詳細介紹」預設只露前幾行,下緣淡出(2026-10-01);用 mask 而不是蓋一層底色,深色模式不用另外對色 */
.ipcs-product-description--clamped {
  max-height: 9rem;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 55%, transparent);
  mask-image: linear-gradient(#000 55%, transparent);
}

/* Stepper（購買方式/選方案兩步）active/done 狀態 + 基礎圓點/分隔線外觀 */
.ipcs-buy-step__num {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--bs-body-bg);
  color: var(--bs-secondary-color);
  font-weight: 600;
  font-size: 14px;
}
.ipcs-buy-step__divider {
  width: 32px;
  height: 2px;
  background: var(--bs-border-color);
}
.ipcs-buy-step.is-active .ipcs-buy-step__num { background: var(--bs-primary) !important; color: #fff !important; }
.ipcs-buy-step.is-active .ipcs-buy-step__label { color: var(--bs-primary) !important; font-weight: 600; }
.ipcs-buy-step.is-done .ipcs-buy-step__num { background: var(--bs-success) !important; color: #fff !important; }
.ipcs-buy-step.is-done .ipcs-buy-step__label { color: var(--bs-secondary-color) !important; }
.ipcs-buy-step.is-done + .ipcs-buy-step__divider { background: var(--bs-success); }

/* Step panel 過場 */
.ipcs-buy-step-panel { animation: stepFadeIn .25s ease; }
@keyframes stepFadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ═══════════════════════════════════════════════════════════════════════════
   B6 — 多語系/文案管理三頁(SiteCopyHub / SiteCopyTable / SiteCopyResx)
   legacy 這些樣式住在各 view 的 @section styles(SPA 沒有那段),搬進共用 CSS。
   值一律沿用模板變數,不新造 token。
   ═══════════════════════════════════════════════════════════════════════════ */

/* 可點卡片的 hover 回饋(Hub 的兩張分流卡)。等價 legacy `.ipcs-hub-tool`
   (SiteCopyHub.cshtml:161-166),改成可共用的通用名。 */
.ipcs-hover-card { transition: border-color .15s ease, box-shadow .15s ease; }
@media (hover: hover) and (pointer: fine) {
  .ipcs-hover-card:hover { border-color: var(--bs-primary) !important; box-shadow: var(--pc-card-box-shadow); }
}

/* 對照表(SiteCopyTable)。等價 legacy `SiteCopyTable.cshtml:150-161` 的 6 條 class;
   legacy view 的 @section styles 過渡期照留不動,B8 拆頁時一起走。 */
.ipcs-copy-matrix th { background: var(--bs-secondary-bg, #f3f5f7); }
.ipcs-matrix-group td { background: var(--bs-tertiary-bg, #eef1f4); }
.ipcs-cell-locked { background: var(--bs-secondary-bg, #f3f5f7); }
.ipcs-cell-status { min-height: 1rem; }
.ipcs-cell-status.is-saving { color: var(--bs-secondary-color, #6c757d); }
.ipcs-cell-status.is-saved { color: var(--bs-success, #2ca87f); }
.ipcs-cell-status.is-error { color: var(--bs-danger, #dc3545); }
.ipcs-cell-input.is-dirty { border-color: var(--bs-warning, #e58a00); }

/* ═══════════════════════════════════════════════════════════════════════════
   B7 — SysAdmin 後台 React 版:圖示 / 底板選擇器的「目前選中」標記
   grid 與 cell 本體是既有樣式(:3865-3916,legacy 已搬進來);legacy 沒有選中標記,
   React 版補上。值沿用該區既有的 primary 色與陰影寫法,不新造 token。
   ═══════════════════════════════════════════════════════════════════════════ */
.ipcs-icon-picker-cell.is-current,
.ipcs-backplate-picker-cell.is-current {
  border-color: var(--bs-primary, #04A9F5);
  box-shadow: 0 0 0 2px rgba(4, 169, 245, 0.2);
}

/* CMS 版本歷史面板的「預覽舞台」:套頁面底色,讓白色 ipcs-showcase-card 浮出來。
   B8-3 從 `Views/Shared/_IpcsCmsHistoryPanel.cshtml` 的 <style> 搬過來 —— 那是全庫
   最後一條還留在 legacy view 裡的樣式,partial 隨 B8 拆掉時 React 的歷史面板會跟著破版。 */
.ipcs-cms-hist-stage { background: var(--bs-body-bg, #f4f7fa); }

/* ── 教學導覽:結束後留著的反白 —— 2026-09-14 已移除 ──────────────────────────
   原本 .ipcs-tour-spotlight 會在導覽結束後把一個呼吸燈留在磚上,閃到使用者點下去為止。
   使用者 2026-09-14:導覽完之後就不要有呼吸燈。driver.js 導覽進行中自己的反白不受影響。 */

/* ═══════ 品牌右鍵選單 + 品牌使用規範頁(2026-08-13)═══════ */

/* 選單本體一律用模板的 .dropdown-menu(圓角/陰影/間距全繼承),這裡只負責「跟著滑鼠座標走」。
   z-index 對齊 Bootstrap 的 $zindex-popover(1070)之上一階:要蓋得過側邊欄(1026),
   但低於 modal(1055)+ backdrop —— modal 開著時本來就不該有右鍵選單浮在上面。 */
.ipcs-brand-menu {
  position: fixed;
  z-index: 1080;
  min-width: 232px;
}

/* 品牌頁:資產列。左預覽、中檔名、右操作,窄螢幕自動堆疊。 */
.ipcs-brand-card + .ipcs-brand-card {
  margin-top: 24px;
}

.ipcs-brand-asset {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding: 16px 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.ipcs-brand-asset:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.ipcs-brand-asset__preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 180px;
  height: 84px;
  padding: 12px;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-card-border-radius, 12px);
  background: #ffffff;
  flex-shrink: 0;
}

/* 白字版字標放白底上等於看不見 —— 預覽底色必須跟著資產走。 */
.ipcs-brand-asset__preview--dark {
  background: #231f1c;
  border-color: #231f1c;
}

.ipcs-brand-asset__preview img {
  max-width: 100%;
  max-height: 100%;
}

.ipcs-brand-asset__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 160px;
}

.ipcs-brand-asset__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* 色票:整塊可點=複製色碼。用 button 而不是 div 才有鍵盤與 focus ring。 */
.ipcs-brand-swatches {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

.ipcs-brand-swatch {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px 10px 10px;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-card-border-radius, 12px);
  background: transparent;
  text-align: start;
}

.ipcs-brand-swatch:hover {
  box-shadow: var(--pc-card-box-shadow, 0px 8px 24px rgba(27, 46, 94, 0.08));
}

.ipcs-brand-swatch__chip {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  flex-shrink: 0;
}

.ipcs-brand-swatch__meta {
  display: flex;
  flex-direction: column;
}

.ipcs-brand-swatch__meta small {
  color: var(--bs-secondary-color);
  letter-spacing: 0.04em;
}

.ipcs-brand-rules {
  margin: 0;
  padding-inline-start: 18px;
}

.ipcs-brand-rules li + li {
  margin-top: 8px;
}

/* ── 註冊:身分選擇卡 ────────────────────────────────────────────────────
   2026-08-24 起這兩張卡是**第一步的岔路**,不是表單裡的單選格:點下去直接前進,
   所以右邊給的是箭號、沒有「選中」這個狀態(舊版的 .border-primary + 打勾已移除)。
   hover 仍是「可以選我」的輕微浮起,不是清單的高亮。

   位移 2px / 0.15s、陰影用卡片 hover 那顆 —— 全部沿用 DESIGN.md 既有值,
   沒有新的 token(2026-08-19)。 */
/* 兩張卡的容器 —— **重點是「永遠等高」**(使用者 2026-08-24:高高低低沒辦法看)。

   用 grid 而不是 Bootstrap 的 row/col,是因為 `grid-auto-rows: 1fr` 會讓**每一列都一樣高**:
   - 桌機:兩張同列 → 一起被拉到較高的那張
   - 手機:上下兩列 → 兩列也被拉成同高
   row/col 只做得到第一種(直排時每張各自成列,各長各的),所以會在手機上露出參差。

   而且不需要任何 min-height 魔術數字 —— 文案改長改短、換成日文英文都自己對齊。 */
.ipcs-register-choices {
  display: grid;
  gap: 1rem;
  grid-auto-rows: 1fr;
}

/* 桌機才並排。手機直排是對的:並排會把說明壓成一行三個字。 */
@media (min-width: 768px) {
  .ipcs-register-choices {
    grid-template-columns: repeat(2, 1fr);
  }

  /* 只有身分選擇那一步放寬(stacked auth 卡預設 460px)——
     並排之後每欄只剩 190px,說明會斷得很碎。第二步是一般表單,維持原寬:
     輸入欄位拉太寬反而難讀。 */
  .auth-main.v2.ipcs-auth-shell-stacked .auth-form.ipcs-register-choice-shell .card {
    max-width: 640px;
  }
}

/* ⚠️ **選擇器一定要帶 `.auth-main.v2 .auth-form` 這段前綴**,不能只寫 .ipcs-register-choice。

   身分卡本身掛著 .card,而同一份檔案上面那條
   `.auth-main.v2 .ipcs-auth-shell .auth-form .card`(5 個 class,見本檔 508 行)
   會一起打到它 —— 它設了 border-color 與 box-shadow。單寫 .ipcs-register-choice:hover
   只有 2 個 class,**整條被吃掉**:hover 與 focus 的陰影都不會出現
   (2026-08-24 用瀏覽器實測才發現,眼睛看不出來)。 */
.auth-main.v2 .auth-form .card.ipcs-register-choice {
  transition: transform 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.auth-main.v2 .auth-form .card.ipcs-register-choice:hover {
  transform: translateY(-2px);
  box-shadow: 0px 8px 20px rgba(41, 52, 74, 0.12);
}

/* 鍵盤焦點**一定要看得見**(WCAG 2.4.7)。

   模板的 .card 把 outline 關掉了,所以只用鍵盤或切換式輔具的人,
   tab 到卡片時畫面上**完全沒有反應** —— 他不知道現在按 Enter 會選到哪一張,
   而選錯的後果是開出一個型別錯誤、且不可逆的租戶(2026-08-24 實測發現)。

   ⚠️ 這條**不能併進 :hover** —— 合併之後會有人把它包進 @media(hover:hover),
   鍵盤焦點樣式就跟著消失(同檔 .ipcs-pp-tile 那邊已經踩過一次,見其註解)。

   ⚠️⚠️ **焦點環不能只用主色**。實測算過:
     - rgba(#04A9F5, .25) 疊在白底 = **1.29:1**
     - 就算 #04A9F5 不透明疊白底也只有 **2.63:1**
   兩個都低於 WCAG 1.4.11 非文字對比要求的 3:1 —— 對弱視的人等於沒有這圈。
   所以**看得見的那一圈用深色 #39465F**(對白底實測 9.48:1,是本檔既有的文字色);
   主色只留一圈柔光,負責「這是我們的顏色」,不負責可見度。

   (原本這裡還寫了 border-color: var(--bs-primary) —— 實測**不會生效**,
   模板有更高特異性的規則壓著它。留一行沒有作用的宣告只會讓下一個人以為邊框會變色,
   所以直接刪掉,不留註解式的謊言。) */
.auth-main.v2 .auth-form .card.ipcs-register-choice:focus-visible {
  outline: 3px solid #39465F;
  outline-offset: 2px;
  box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
}

/* 深色底下 #39465F 只剩 1.7:1(對卡片背景 #1b232d)—— 換成淺色的那一圈。
   #dbe0e5 是模板的 --bs-gray-300 / --bs-border-color,對 #1b232d 是 11.9:1。 */
body[data-pc-theme='dark'] .auth-main.v2 .auth-form .card.ipcs-register-choice:focus-visible {
  outline-color: #dbe0e5;
}

/* ── 註冊:換步驟時淡入 ─────────────────────────────────────────────────
   身分選好之後整段換掉,直接抽換會「啪」一下。**只做 opacity,不做位移** ——
   兩步的內容高度差很多,再疊上位移會讓人覺得畫面往某個方向跑掉。

   0.15s ease-in-out 是本專案既有的 transition 值(與上面那張卡同一顆),
   沒有新的 token(2026-08-24)。 */
@keyframes ipcs-register-step-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.ipcs-register-step {
  animation: ipcs-register-step-in 0.15s ease-in-out;
}

/* 會暈眩的人把動效關掉就真的不要動 —— 淡入只是輔助,拿掉不影響可用性。 */
@media (prefers-reduced-motion: reduce) {
  .ipcs-register-step {
    animation: none;
  }
}

/* 會暈眩的人把動效關掉就真的不要動 —— 位移本來就只是輔助,拿掉不影響可用性。
   前綴要跟上面那組一致,否則蓋不過去(同樣的特異性陷阱)。
   **只拿掉位移與過場,不動 focus 的那圈** —— 那是資訊,不是動效。 */
@media (prefers-reduced-motion: reduce) {
  .auth-main.v2 .auth-form .card.ipcs-register-choice {
    transition: none;
  }

  .auth-main.v2 .auth-form .card.ipcs-register-choice:hover {
    transform: none;
  }
}

/* 稽核紀錄:複選篩選(frontend/src/pages/audit/AuditMultiSelect.tsx,2026-09-30)。
   外觀全部是模板的 .form-select / .dropdown-menu / .dropdown-item / .form-check-input,
   這裡只補模板沒有的兩件事:選項多時(使用者可能上百人)清單限高、在選單裡捲動,
   以及整列都是勾選的命中區(label),游標要看得出來可以點。 */
.ipcs-multiselect__options {
  max-height: 16rem;
  overflow-y: auto;
}

.ipcs-multiselect__options .dropdown-item {
  cursor: pointer;
}

/* ─────────────────────────────────────────────────────────────
   容量用量(2026-10-02,frontend/src/pages/usage/、shell/UsageBanner.tsx)
   模板沒有「呼吸提示點」—— 使用者要求 90% 以上紅色呼吸提示,所以自訂。
   色彩一律用模板的 --bs-danger-rgb,不另訂顏色。
   ───────────────────────────────────────────────────────────── */
.ipcs-usage-pulse {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgb(var(--bs-danger-rgb));
  box-shadow: 0 0 0 0 rgba(var(--bs-danger-rgb), 0.6);
  animation: ipcs-usage-breathe 1.6s ease-out infinite;
  vertical-align: middle;
}

.ipcs-usage-pulse-badge {
  animation: ipcs-usage-badge-breathe 1.6s ease-in-out infinite;
}

@keyframes ipcs-usage-breathe {
  0% { box-shadow: 0 0 0 0 rgba(var(--bs-danger-rgb), 0.6); }
  70% { box-shadow: 0 0 0 8px rgba(var(--bs-danger-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--bs-danger-rgb), 0); }
}

@keyframes ipcs-usage-badge-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

/* 系統清單的一列(<button class="list-group-item">):選中的那列用主色淡底 + 左側主色線,
   不用 Bootstrap 的 .active(整列主色實心,列裡的比例條、紅色標籤會看不清楚)。 */
.ipcs-usage-row.is-active {
  background: rgba(var(--bs-primary-rgb), 0.08);
  box-shadow: inset 3px 0 0 rgb(var(--bs-primary-rgb));
}

/* 側邊欄「容量用量」:有系統到 90% 以上 → 整列紅字 + 紅色呼吸底與框(使用者 2026-10-02 要更明顯)。
   做法照模板 active 那一列:模板用 .pc-link::after 鋪一層色、opacity 0.1;這裡同一層換成紅色、讓它呼吸。 */
.pc-sidebar .pc-navbar > .pc-item.ipcs-nav-alert > .pc-link {
  color: rgb(var(--bs-danger-rgb));
  font-weight: 500;
}

.pc-sidebar .pc-navbar > .pc-item.ipcs-nav-alert > .pc-link::after {
  background: rgb(var(--bs-danger-rgb));
  box-shadow: inset 0 0 0 1px rgb(var(--bs-danger-rgb));
  animation: ipcs-nav-alert-breathe 1.8s ease-in-out infinite;
}

@keyframes ipcs-nav-alert-breathe {
  0%, 100% { opacity: 0.06; }
  50% { opacity: 0.22; }
}

@media (prefers-reduced-motion: reduce) {
  .ipcs-usage-pulse,
  .ipcs-usage-pulse-badge {
    animation: none;
  }
  .pc-sidebar .pc-navbar > .pc-item.ipcs-nav-alert > .pc-link::after {
    animation: none;
    opacity: 0.14;
  }
}

/* ─── 公告管理(2026-10-02):新增 / 修改頁右邊的預覽,寬螢幕時跟著捲動停在畫面上 ─── */
@media (min-width: 1200px) {
  .ipcs-announcement-preview {
    position: sticky;
    top: 90px;
  }
}

/* 最多兩行、保留換行(登入卡片裡的公告內文,2026-10-02) */
.ipcs-line-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: pre-wrap;
}

/* ── 副色(2026-10-06):商業焦點的按鈕(升級方案)。docs/IPCS/配色層級_規劃.md §3 ──────────
   使用者:「升級方案畫面上現在是淺色的,請改為深色重一點,滑入的時候再不同樣式」;副色「預設先用橘色」。
   深橘實心 #C2410C 白字 5.18:1、滑入 #9A3412 白字 7.3:1(WCAG AA 4.5:1 以上,淺色、深色模式都一樣)。
   ⚠️ 不叫 --ipcs-accent:那個名字已經是 preset 主色(工作入口的分頁在用)。圓角、字級沿用模板 .btn。 */
:root {
  --ipcs-sub-accent: #c2410c;
  --ipcs-sub-accent-hover: #9a3412;
  --ipcs-sub-accent-shadow: rgba(194, 65, 12, 0.35);
  --ipcs-sub-accent-ring: rgba(194, 65, 12, 0.5);
}
/* 外觀設定可以換(2026-10-07 使用者:「試用綠／升級橘應該都要可以在外觀設定改」)。
   只給驗過對比的色票,不收任意色碼(配色層級_規劃.md §3):白字 on 實心 / 滑入 ——
   莓紅 6.04 / 7.88、紫 7.10 / 8.98、靛藍 7.90 / 9.93(深色模式同一組,實心白字不受底色影響)。 */
body[data-ipcs-sub-accent='berry'] {
  --ipcs-sub-accent: #be185d;
  --ipcs-sub-accent-hover: #9d174d;
  --ipcs-sub-accent-shadow: rgba(190, 24, 93, 0.35);
  --ipcs-sub-accent-ring: rgba(190, 24, 93, 0.5);
}
body[data-ipcs-sub-accent='violet'] {
  --ipcs-sub-accent: #6d28d9;
  --ipcs-sub-accent-hover: #5b21b6;
  --ipcs-sub-accent-shadow: rgba(109, 40, 217, 0.35);
  --ipcs-sub-accent-ring: rgba(109, 40, 217, 0.5);
}
body[data-ipcs-sub-accent='indigo'] {
  --ipcs-sub-accent: #4338ca;
  --ipcs-sub-accent-hover: #3730a3;
  --ipcs-sub-accent-shadow: rgba(67, 56, 202, 0.35);
  --ipcs-sub-accent-ring: rgba(67, 56, 202, 0.5);
}
.btn.ipcs-btn-sub-accent {
  background: var(--ipcs-sub-accent);
  border-color: var(--ipcs-sub-accent);
  color: #fff;
  transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.btn.ipcs-btn-sub-accent:hover {
  background: var(--ipcs-sub-accent-hover);
  border-color: var(--ipcs-sub-accent-hover);
  color: #fff;
  box-shadow: 0 6px 16px var(--ipcs-sub-accent-shadow);
}
/* 鍵盤聚焦:外圈一定要有(兩種橘之間只差約 1.4:1,只換底色用鍵盤的人看不出焦點在哪) */
.btn.ipcs-btn-sub-accent:focus-visible {
  background: var(--ipcs-sub-accent-hover);
  border-color: var(--ipcs-sub-accent-hover);
  color: #fff;
  box-shadow: 0 0 0 0.2rem var(--ipcs-sub-accent-ring);
}
.btn.ipcs-btn-sub-accent:active {
  background: var(--ipcs-sub-accent-hover);
  border-color: var(--ipcs-sub-accent-hover);
  color: #fff;
  box-shadow: none;
}
@media (hover: hover) {
  .btn.ipcs-btn-sub-accent:hover {
    transform: translateY(-1px);
  }
}

/* ── 試用按鈕(2026-10-07):產品卡、方案頁試用卡、舊購買頁的「立即試用」都用這一個 ──────────
   使用者:「點進去裡面如果是試用版的,配色是不是也要和外面的試用按鈕一樣」。原本的 btn-light-success
   是模板的亮綠字(#2ca87f 類),淡底上不到 4.5:1。這裡改深綠 #15735B(本檔 emerald 已在用的色):
   淡底 #E6F4EF 深綠字 5.10:1、滑入實心 #15735B 白字 5.78:1;深色模式 #173D33 底 #6EE7B7 字 7.86:1。
   跟模板 btn-light-* 同一個行為:平常淡底、滑入變實心。 */
:root {
  --ipcs-trial: #15735b;
  --ipcs-trial-tint: #e6f4ef;
  --ipcs-trial-ring: rgba(21, 115, 91, 0.45);
  --ipcs-trial-glow: rgba(21, 115, 91, 0.16);
  --ipcs-trial-dark-bg: #173d33;
  --ipcs-trial-dark-text: #6ee7b7;
}
/* 外觀設定可以換(2026-10-07),一樣只給驗過的色票。淡底上的字 / 實心白字 / 深色模式的字:
   青 4.70 / 5.36 / 8.40、藍 5.77 / 6.70 / 7.56、紫 6.07 / 7.10 / 7.95 */
body[data-ipcs-trial-tone='teal'] {
  --ipcs-trial: #0e7490;
  --ipcs-trial-tint: #e2f3f8;
  --ipcs-trial-ring: rgba(14, 116, 144, 0.45);
  --ipcs-trial-glow: rgba(14, 116, 144, 0.16);
  --ipcs-trial-dark-bg: #133a47;
  --ipcs-trial-dark-text: #67e8f9;
}
body[data-ipcs-trial-tone='blue'] {
  --ipcs-trial: #1d4ed8;
  --ipcs-trial-tint: #e8eefc;
  --ipcs-trial-ring: rgba(29, 78, 216, 0.45);
  --ipcs-trial-glow: rgba(29, 78, 216, 0.16);
  --ipcs-trial-dark-bg: #1b2b57;
  --ipcs-trial-dark-text: #a5c0fd;
}
body[data-ipcs-trial-tone='violet'] {
  --ipcs-trial: #6d28d9;
  --ipcs-trial-tint: #f1eafd;
  --ipcs-trial-ring: rgba(109, 40, 217, 0.45);
  --ipcs-trial-glow: rgba(109, 40, 217, 0.16);
  --ipcs-trial-dark-bg: #2f2158;
  --ipcs-trial-dark-text: #c9b8fd;
}
.btn.ipcs-btn-trial {
  background: var(--ipcs-trial-tint);
  border-color: var(--ipcs-trial-tint);
  color: var(--ipcs-trial);
}
.btn.ipcs-btn-trial:hover,
.btn.ipcs-btn-trial:active {
  background: var(--ipcs-trial);
  border-color: var(--ipcs-trial);
  color: #fff;
}
.btn.ipcs-btn-trial:focus-visible {
  background: var(--ipcs-trial);
  border-color: var(--ipcs-trial);
  color: #fff;
  box-shadow: 0 0 0 0.2rem var(--ipcs-trial-ring);
}
body[data-pc-theme='dark'] .btn.ipcs-btn-trial {
  background: var(--ipcs-trial-dark-bg);
  border-color: var(--ipcs-trial-dark-bg);
  color: var(--ipcs-trial-dark-text);
}
body[data-pc-theme='dark'] .btn.ipcs-btn-trial:hover,
body[data-pc-theme='dark'] .btn.ipcs-btn-trial:active,
body[data-pc-theme='dark'] .btn.ipcs-btn-trial:focus-visible {
  background: var(--ipcs-trial);
  border-color: var(--ipcs-trial);
  color: #fff;
}
/* 方案頁的試用卡跟著試用色走(裡外同色):卡頭淡底、徽章實心白字、火箭圖示 */
.ipcs-trial-head { background: var(--ipcs-trial-tint); }
.ipcs-trial-badge { background: var(--ipcs-trial); color: #fff; }
.ipcs-trial-icon { color: var(--ipcs-trial); }
body[data-pc-theme='dark'] .ipcs-trial-head { background: var(--ipcs-trial-dark-bg); }
body[data-pc-theme='dark'] .ipcs-trial-icon { color: var(--ipcs-trial-dark-text); }

/* 外觀設定裡的色票 */
.ipcs-accent-option__swatch--sub-default { background: #c2410c; }
.ipcs-accent-option__swatch--sub-berry { background: #be185d; }
.ipcs-accent-option__swatch--sub-violet { background: #6d28d9; }
.ipcs-accent-option__swatch--sub-indigo { background: #4338ca; }
.ipcs-accent-option__swatch--trial-default { background: #15735b; }
.ipcs-accent-option__swatch--trial-teal { background: #0e7490; }
.ipcs-accent-option__swatch--trial-blue { background: #1d4ed8; }
.ipcs-accent-option__swatch--trial-violet { background: #6d28d9; }

/* 方案頁的區段跳轉(方案 → 加購容量 / 服務項目):捲過去時不要被固定的頂列(74px)蓋住標題 */
.ipcs-billing-anchor {
  scroll-margin-top: 90px;
}
/* 跳轉時焦點會移到區塊上(tabindex=-1):滑鼠點的不畫外框,鍵盤來的照常畫,讓人知道現在在哪 */
.ipcs-billing-anchor:focus:not(:focus-visible) {
  outline: none;
}

/* 選公司的清單(2026-10-08,寄信給客戶/各公司稽核/通知服務設定):全部列出、可以捲動點選;上面的輸入框只是篩選 */
.ipcs-company-list {
  max-height: 280px;
  overflow-y: auto;
}

/* 寄信給客戶的所見即所得(2026-10-08):信放在灰底上,像在信件軟體裡看;手機模式把信縮到手機寬 */
.ipcs-mail-canvas {
  background: var(--bs-tertiary-bg);
  border-radius: 12px;
  padding: 16px;
}
.ipcs-mail-frame {
  display: block;
  width: 100%;
  min-height: 360px;
  border: 0;
  margin: 0 auto;
}
/* 寄出時的樣子:sandbox 不給權限,量不到裡面多高 → 固定高度、在框裡捲 */
.ipcs-mail-frame--preview {
  height: 70vh;
}
.ipcs-mail-canvas--mobile .ipcs-mail-frame,
.ipcs-mail-canvas--mobile .ipcs-mail-fallback {
  max-width: 390px;
  margin: 0 auto;
}
/* 拿不到通知中心外框時的單純編輯框 */
.ipcs-mail-fallback {
  min-height: 240px;
  height: auto;
  overflow-wrap: anywhere;
}
.ipcs-mail-fallback:empty::before {
  content: attr(data-placeholder);
  color: var(--bs-secondary-color);
}
/* 工具列的文字顏色色塊(顏色本身是信件樣式規範定的 4 個字色) */
.ipcs-mail-swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid var(--bs-border-color);
  vertical-align: middle;
}
.ipcs-mail-attachment .btn-close {
  font-size: 0.6rem;
}

/* 開通中的提示(2026-10-08,試用、付款成功後等 AUTH 開通入口):固定在右下角、不擋操作;
   在頂列(1025)、側邊欄(1026)、對話框之下 —— 手機打開側邊欄時不會蓋住底部的使用者選單 */
.ipcs-activation-watch {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 1024;
  width: min(360px, calc(100vw - 32px));
}
@media (max-width: 575.98px) {
  .ipcs-activation-watch {
    right: 16px;
    bottom: 16px;
  }
}

/* 快速入口(2026-10-08):工地 QR 的大小(列印另外在新視窗排版,見 quickEntryModel.printSheetHtml) */
.ipcs-qe-qr {
  width: 200px;
  height: 200px;
  max-width: 100%;
}

/* ── AI 小幫手面板(2026-10-09,右上角對話泡泡)──
   固定在右上內容區(頂欄 74px / 手機 60px 下方),寬最多 400px、高 560px,不跟著訊息變高;只有問答區捲動。
   面板 portal 到 body(HelperButton.tsx)。z-index 1020:在頁面內容上面、頂欄(1025)與側邊欄底下 ——
   頂欄的下拉選單(導覽、鈴鐺、語言)打開時才不會被面板蓋住。 */
.ipcs-helper-panel {
  position: fixed;
  top: 82px;
  right: 16px;
  z-index: 1020;
  width: min(400px, calc(100vw - 32px));
  height: min(560px, calc(100vh - 98px));
  margin-bottom: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.ipcs-helper-panel[hidden] {
  display: none;
}
/* App 內(WebView)頂欄是 56px + 瀏海的 safe-area */
body.ipcs-in-app .ipcs-helper-panel {
  top: calc(64px + env(safe-area-inset-top));
  height: min(560px, calc(100vh - 80px - env(safe-area-inset-top)));
}
@media (max-width: 1024px) {
  .ipcs-helper-panel {
    top: 68px;
    height: min(560px, calc(100vh - 84px));
  }
}
.ipcs-helper-panel__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px;
}
.ipcs-helper-panel__head > i {
  font-size: 22px;
}
.ipcs-helper-panel__faq {
  padding: 12px 16px 0;
}
.ipcs-helper-panel__log {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ipcs-helper-panel__form {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--bs-border-color);
}
.ipcs-helper-panel__form textarea {
  resize: none;
}
.ipcs-helper-panel__form .btn {
  flex-shrink: 0;
  white-space: nowrap;
}
.ipcs-helper-msg {
  max-width: 92%;
  padding: 8px 12px;
  border-radius: 8px;
}
.ipcs-helper-msg__text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.ipcs-helper-msg--user {
  align-self: flex-end;
  background: var(--bs-primary-bg-subtle);
  color: var(--bs-body-color);
}
.ipcs-helper-msg--assistant {
  align-self: flex-start;
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

/* 回答裡可以點的平台功能:點了只標出它在畫面上的位置(不進去) */
/* 2026-10-09 使用者:標籤跟淺藍的提問泡泡太像 → 照簽核專區的範例改成白底、藍框、藍字的膠囊。
   字色 #0c7bb8(本檔既有的主色深一階,白底對比約 4.6:1,過 AA);深色模式改淺藍字。 */
.ipcs-helper-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin: 0 2px;
  padding: 0 10px;
  border: 1px solid rgba(4, 169, 245, 0.45);
  border-radius: 50rem;
  background: var(--bs-body-bg);
  color: #0c7bb8;
  font: inherit;
  line-height: 1.7;
  vertical-align: baseline;
  cursor: pointer;
}
.ipcs-helper-chip:hover,
.ipcs-helper-chip:focus-visible {
  border-color: var(--bs-primary);
  background: rgba(4, 169, 245, 0.06);
}
body[data-pc-theme=dark] .ipcs-helper-chip {
  color: #7cc8f0;
  border-color: rgba(4, 169, 245, 0.5);
}

/* ── 互動式導覽:從哪一步開始的清單(2026-10-09)── */
.ipcs-tour-picker {
  min-width: 240px;
  max-height: 70vh;
  overflow-y: auto;
}
.ipcs-tour-picker .dropdown-item {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ipcs-tour-picker__no {
  min-width: 1.5em;
  text-align: right;
  color: var(--bs-secondary-color);
  font-variant-numeric: tabular-nums;
}
