@charset "UTF-8";
/* ── 字型：消除重新整理時文字抖動 ──────────────────────────────
   Radzen 主題 CSS 的內文字型宣告 font-display: swap，
   瀏覽器先用系統字畫一頁，字型下載完才換成主題字型 → 整頁文字重新排版，
   看起來就是「字抖一下」。material 用的 RobotoFlex.woff2 有 747KB，最明顯。

   下面用相同的 family / src / weight 重宣告一次並改成 font-display: optional：
   字型在極短時間內沒到位就直接用系統字，而且當次載入不再換回來。
   搭配 App.razor 的 <link rel="preload">，正常情況下字型都會贏；
   贏不了時也只是用系統字，不會跳動 —— 兩種情況都不抖。

   沒動 Material Symbols：那是圖示字型（ligature），沒給它字型時會直接顯示
   「settings」這類文字而不是圖示。Radzen 已經 preload 它，維持原狀即可。 */
@font-face {
    font-family: "Roboto";
    src: url("/_content/Radzen.Blazor/fonts/RobotoFlex.woff2") format("woff2-variations");
    font-weight: 100 1000;
    font-display: optional;
}

@font-face {
    font-family: "Source Sans Pro";
    src: url("/_content/Radzen.Blazor/fonts/SourceSans3VF-Upright.ttf.woff2") format("woff2-variations");
    font-weight: 200 900;
    font-display: optional;
}

@font-face {
    font-family: "Source Sans Pro";
    src: url("/_content/Radzen.Blazor/fonts/SourceSans3VF-Italic.ttf.woff2") format("woff2-variations");
    font-style: italic;
    font-weight: 200 900;
    font-display: optional;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

:root {
    font-size: var(--rz-root-font-size);
}

body {
    font-family: var(--rz-text-font-family);
    color: var(--rz-text-color);
    font-size: var(--rz-body-font-size);
    line-height: var(--rz-body-line-height);
    background-color: var(--rz-body-background-color);
}

.rz-body {
    --rz-body-padding: 0;
}

a {
    color: var(--rz-link-color);
}

a:hover,
a:focus {
    color: var(--rz-link-hover-color);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

.loading-progress circle {
    fill: none;
    stroke: #e0e0e0;
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}

.loading-progress circle:last-child {
    stroke: #1b6ec2;
    stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
    transition: stroke-dasharray 0.05s ease-in-out;
}

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

.loading-progress-text:after {
    content: var(--blazor-load-percentage-text, "Loading");
}

/* 頁面標題列（抄 radzen飛鼠系統「客戶出貨維護」.ship-header h1）：
   標題 1.4rem 且去除瀏覽器預設 margin，圖示＋徽章靠 RadzenStack 對齊。 */
.page-header h1 {
    margin: 0;
    font-size: 1.4rem;
}

/* 首欄展開鈕：桌機只秀圖示箭頭，文字鈕藏起來（手機版才秀，見下方 768px 區）。
   RadzenButton 吃 class 參數（併入原生 rz-button 類別），這裡只管顯示切換，
   點了都走同一個 切換展開Async。 */
.life-policy-grid .grid-expand-text {
    display: none;
}

/* 共用查詢 Grid（查詢Grid_v1）：過濾列首欄的「清除」鈕拉到跟過濾輸入框同高
   （原本 Small 鈕 28px、輸入框 36px，格底不齊；使用者 2026-10-20 提出）。
   高度吃主題 token --rz-input-height，深淺主題／各主題都跟輸入框同一個值。
   目標：過濾列在 THEAD（格是 th），鈕包在 th＞.rz-cell-filter＞.rz-cell-filter-content 裡。 */
.query-grid-v1 .rz-cell-filter .rz-button {
    height: var(--rz-input-height);
    min-height: var(--rz-input-height);
}


/* 測試頁手機卡片（壽險保單查詢測試）：768px 以下藏 Grid 秀卡片，以上相反。
   純 CSS 切換，SSR 也生效；卡片欄位讀 Grid Columns 中繼資料，單一來源。 */
@media (max-width: 768px) {
    .test-grid-desktop {
        display: none;
    }

    /* 手機版：圖示箭頭藏起來，改秀文字鈕（展開明細／收合明細，跟測試頁同字樣）。
       格子照樣沉底（下方 order 規則），所以文字鈕落在卡片最後一格。 */
    .life-policy-grid .grid-expand-icon {
        display: none;
    }
    .life-policy-grid .grid-expand-text {
        /* 不要用 inline-flex：那會讓按鈕自己變 flex 容器，內容改吃 flex 排列而靠左
           （CDP 實測內容左偏移 12px／右偏移 196px）。主題的 .rz-button 本來是
           inline-block，內容靠瀏覽器對按鈕預設的 text-align:center 置中；
           這裡寫 block＋text-align:center，跟壽險保單查詢測試的卡片按鈕一致
           （那邊量到左/右各偏移 62px，置中）。 */
        display: block;
        width: 100%;
        text-align: center;
    }

    /* 回應（Responsive）模式：展開／收合明細的箭頭寫在第 0 欄，儲存格堆疊後
       會跑到整張卡片的最上方，一列開始就是箭頭很礙眼。
       資料列改成「兩欄格線」：每列放兩個 {標題：值}（原本一欄一列，卡片拉得
       很長），只把首格（展開／清除鈕）order 置後並橫跨兩欄，沉到卡片底部。
       用子選擇器只鎖主表自己的列（.life-policy-grid 下第一層 Grid），
       明細裡的小 Grid 列不受影響（它們照自己的 reflow 堆疊，見下方）。
       換頁/排序後 DOM 重排，:nth-child(even) 條紋仍由 td 決定，不受影響。 */
    .life-policy-grid > .rz-data-grid > .rz-data-grid-data > table > tbody > tr.rz-data-row {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
        column-gap: 0.75rem;
    }
    .life-policy-grid > .rz-data-grid > .rz-data-grid-data > table > tbody > tr.rz-data-row > td:first-child {
        order: 1;
        grid-column: 1 / -1;
    }

    /* 壽險保單查詢（額外Class="life-policy-query"）：保單狀況自己佔第一列、
       橫跨兩欄（chip 本身照內容寬，只靠左），其餘欄位照兩欄排。
       欄位用 :has(.rz-chip) 認 —— 這一頁只有「保單狀況」欄會渲染 RadzenChip，
       之後欄位順序或顯示欄位增減都不會跑掉（比 nth-child 位置法穩）。
       order:-1 排在最前面（展開／清除鈕那格是 order:1，永遠沉底）。 */
    .life-policy-grid.life-policy-query > .rz-data-grid > .rz-data-grid-data > table > tbody > tr.rz-data-row > td:has(.rz-chip) {
        order: -1;
        grid-column: 1 / -1;
    }
    /* 展開明細鈕那一格（有按鈕才吃，沒有明細的頁首格是空的，別多留 24px 空白）：
       比照壽險保單查詢測試手機卡片的位置 —— 測試頁的按鈕放在 RadzenCard 裡
       （卡片內距 20px），所以按鈕離卡片左/右/下緣各 20px。這裡的「卡片」是 reflow
       的資料列，儲存格原本只吃 4px 8px 內距，按鈕幾乎貼著卡片邊（實測左 12／右 8／
       距底 4）。補成同樣的 20px 內距；上緣維持 4px（跟前一欄的 4px 合計 8px，
       等同測試頁卡片裡的行距）。 */
    .life-policy-grid > .rz-data-grid > .rz-data-grid-data > table > tbody > tr.rz-data-row > td:first-child:has(.grid-expand-text) {
        padding: 4px 20px 20px;
        /* 這格的欄名是空 span，但仍會吃到 reflow 的 4px 欄距，讓按鈕左右不對稱
           （左 12／右 8）；這一格直接關掉欄距。 */
        gap: 0;
    }

    /* 條紋底色（偶數列）原本由主題上在 td 上：卡片改兩欄後，同一列裡較矮的
       格子只塗到自己內容的高度，旁邊就會露出一塊沒上色的空白（換行的另一格
       比較高）。改成塗在整張卡片（tr＝我們的 grid 容器）上、td 透明，
       底色就跟著卡片高度鋪滿；卡片高度本來就是該列最高的那個格子。
       掛 .life-policy-grid + table 兩層，特異度壓過主題的
       .rz-grid-table-striped tbody > tr:nth-child(2n) > td（0,3,3）。 */
    .life-policy-grid > .rz-data-grid > .rz-data-grid-data > table.rz-grid-table-striped > tbody > tr:not(.rz-expanded-row-content):nth-child(2n) > td {
        background-color: transparent;
    }

    .life-policy-grid > .rz-data-grid > .rz-data-grid-data > table.rz-grid-table-striped > tbody > tr:not(.rz-expanded-row-content):nth-child(2n) {
        background-color: var(--rz-grid-stripe-background-color);
    }

    /* 回應模式：明細展開列要「滿版 block」。
       Radzen 的 reflow 規則只把資料列（.rz-data-row）改成 block，展開列
       （.rz-expanded-row-content）留著 display:table-row／table-cell，可是它的母表格
       已被改成 display:block —— tr 就被包進匿名表格，寬度縮成內容寬
       （CDP 實測 tr/td 剩 18px、明細容器只剩 2px），看起來就是「明細整片不見」。
       改成 block＋100% 後展開列撐滿卡片寬；內層明細 Grid 自己也 Responsive，
       照 Radzen 的 reflow 規則堆疊（欄位標題在上、值在下）。
       （壽險商品來佣率、產險商品來佣率；其他頁明細這樣改也不影響。） */
    .life-policy-grid .rz-expanded-row-content {
        display: block;
    }
    .life-policy-grid .rz-expanded-row-content > td {
        display: block;
        width: 100%;
    }

    /* 明細裡的表格式小 Grid（目前：壽險保單查詢的「投保商品」）在手機維持 GridView
       （表格＋表頭＋合計列）型式，不跟主表一起變卡片堆疊。
       兩個地方要用到同一組規則，所以選擇器開頭用 :is() 併起來：
         (1) 內嵌展開列 .life-policy-grid .rz-expanded-row-content（原本的明細）
         (2) 明細彈窗 .detail-popup（查詢Grid_v1 的「明細彈窗」參數開的對話框；
             對話框掛在版面最外層、不在 .life-policy-grid 裡，構不到上面那條）

       主表的 reflow 規則以 .rz-datatable-reflow 為根、會穿透到內層 Grid：把表格
       block 化、儲存格改成 width:100% !important／文字靠左 !important／拿掉框線，
       這裡逐項還原成表格；表格比畫面寬，橫向捲動交給 Radzen 自己的資料容器
       （明細容器已有 overflow-x）。 */
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-grid-data > table,
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-datatable-scrollable-header-box > table {
        display: table;
        table-layout: fixed;
    }
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-grid-data > table > tbody {
        display: table-row-group;
    }
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview thead th {
        display: table-cell;
    }
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row {
        display: table-row;
    }
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row > td {
        display: table-cell;
        width: auto !important;   /* reflow 是 width:100% !important，得 !important 蓋回 */
        border-bottom: var(--rz-grid-bottom-cell-border);
    }
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row > td:not(:last-child) {
        border-inline-end: var(--rz-grid-right-cell-border);
    }

    /* 欄位對齊：Radzen 的 TextAlign 寫在行內樣式（style="text-align:right"），
       行內樣式不敵 reflow 的 text-align:left !important，只能用同樣 !important
       依行內值還原（右／中兩種；其餘維持 left）。 */
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row > td[style*="text-align:right"],
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row > td[style*="text-align: right"] {
        text-align: right !important;
    }
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row > td[style*="text-align:center"],
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row > td[style*="text-align: center"] {
        text-align: center !important;
    }

    /* 表格型式不需要卡片式的欄位標題（表頭 th 已顯示欄名）；
       合計列（tfoot）照常顯示 —— 下面那兩條「明細不顯示 tfoot」特異度較低，會被這條蓋掉。 */
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-data-row > td .rz-column-title {
        display: none;
    }
    :is(.life-policy-grid .rz-expanded-row-content, .detail-popup) .detail-gridview .rz-datatable-tfoot {
        display: table-footer-group;
    }

    /* 回應模式：明細裡「卡片堆疊」小 Grid 的 footer（合計列）不顯示
       （卡片型式下合計列擠在欄位卡片裡不好讀）。
       內嵌展開列與明細彈窗都套用（彈窗裡的小 Grid 一樣是卡片堆疊）；
       上面 .detail-gridview（GridView 型式）那條特異度較高，它的合計列照常顯示。 */
    .life-policy-grid .rz-expanded-row-content .rz-datatable-tfoot,
    .detail-popup .rz-datatable-tfoot {
        display: none;
    }

    /* 回應模式：測試頁手機卡片裡的明細投保商品 footer 也不顯示。
       卡片明細是直嵌（不在展開列裡），上面那條構不到，這裡只鎖測試頁卡片容器；
       桌機版（測試頁 Tab 明細）footer 照常顯示。 */
    .test-cards-mobile .rz-datatable-tfoot {
        display: none;
    }

    /* 共用查詢 Grid（查詢Grid_v1）：手機版不收 tfoot 合計列（桌機照常）。
       靠元件外層多掛的 .query-grid-v1 定位，不動其他 .life-policy-grid 使用者。 */
    .query-grid-v1 .rz-datatable-tfoot {
        display: none;
    }

    /* ── reflow 卡片的欄位排版：{欄名（粗體）}：{值} 同在一行 ──────────────
       Radzen reflow 原生是「欄名一行、值一行」（td 內兩個 block span），
       這裡把 td 改成 flex（可換行）讓兩者並排，欄名加粗並補一個全形冒號。

       影響範圍＝所有 reflow 卡片：主表卡片、明細裡卡片堆疊的小 Grid（受益人／
       掃描檔／契約服務…）都一起改；明細裡「表格型式」的小 Grid（投保商品）不受
       影響 —— 它把 .rz-column-title 藏掉了，那條規則特異度（0,5,1）比這裡高。

       特異度：td 那條刻意掛三層 class（.rz-datatable.rz-datatable-reflow），
       壓過 Radzen 自己的 .rz-datatable-reflow .rz-data-row>td（兩層，display:block），
       免得同分靠檔案順序；欄名兩條只掛兩層＋:not(:empty)（三層），維持低於明細
       表格那條。:not(:empty) 是為了「展開鈕」那一格（欄名是空 span）不冒出「：」。 */
    .rz-datatable.rz-datatable-reflow .rz-data-row > td {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0 0.25rem;
    }

    .rz-datatable-reflow .rz-data-row > td > .rz-column-title:not(:empty) {
        font-weight: 700;
    }

    .rz-datatable-reflow .rz-data-row > td > .rz-column-title:not(:empty)::after {
        content: "：";
    }

    /* 值吃掉剩下的寬度；值本身是 nowrap＋ellipsis（Radzen 的 .rz-text-truncate），
       min-width:0 讓它可以縮、不要撐破卡片。
       卡片改兩欄後每格只剩一半寬，長值（保單號碼、地址）若照舊 nowrap 會被截成
       …，所以改成可折行、最多兩行（-webkit-line-clamp），再長才省略；
       有按鈕／連結的儲存格（首欄展開／清除）不套用，免得破壞按鈕排版。 */
    .rz-datatable-reflow .rz-data-row > td > .rz-cell-data {
        flex: 1 1 auto;
        min-width: 0;
    }

    .rz-datatable-reflow .rz-data-row > td > .rz-cell-data:not(:has(button, a)) {
        white-space: normal;
        overflow-wrap: anywhere;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
    }

    /* ── 明細卡片的欄位列：reflow 也走 {標題（粗體）}：{值} ───────────────
       來源標記（壽險保單明細、壽險保單明細測試、照會單詳細同一套）：
       <b>標題</b><br>值，桌機維持「標題一行、值一行」。手機比照卡片排版：
       <br> 藏掉、標題後面補全形冒號，變成「壽險公司：臺銀人壽」同一行；
       標題本來就是 <b>，粗體免加。（要不要整區變卡片？它是 RadzenRow/RadzenColumn，
       Size=12 本來就會一欄一列排下來，不用改結構。） */
    .detail-fields br {
        display: none;
    }
    .detail-fields b::after {
        content: "：";
    }

    /* 保單狀況（chip）排到卡片第一列 —— 跟主表卡片同一個做法
       （主表是 .life-policy-grid.life-policy-query 的 td:has(.rz-chip)）。
       欄位用 :has(.rz-chip) 認，欄位順序或顯示欄位增減都不會跑掉；
       order 只動視覺順序，桌機不在這個 media query 內、欄位順序照舊。 */
    .detail-fields > *:has(.rz-chip) {
        order: -1;
    }

    /* ── 明細彈窗（查詢Grid_v1 的明細一律用彈窗開）：底部留一截 ──────────
       主題在 ≤768px 就把對話框規定成 position:absolute／inset-block-start:0／
       width:100% !important／border-radius:0，高度於是撐滿整個畫面；這裡只補
       「高度 90vh＋下方圓角」，讓它看起來是浮在原本畫面上的一層明細，而不是
       換了一頁（下方那一截看得到被遮暗的原頁面）。
       對話框本身 overflow:hidden，圓角會把裡面的內容一起裁掉，不會有方角冒出來。
       高度兩行是 vh／dvh 的退路：手機網址列伸縮時 dvh 才算得準，舊瀏覽器吃 vh。
       選擇器刻意掛到四層（.rz-dialog-wrapper > .rz-dialog.detail-popup-dialog.rz-open；
       Radzen 12 的對話框是 wrapper 裡放 .rz-dialog，遮罩在 wrapper 外面），
       才壓得過主題那條 .rz-dialog:not(…):not(…)（三層，border-radius:0），
       不必靠 site.css 排在主題後面這件事。 */
    .rz-dialog-wrapper > .rz-dialog.detail-popup-dialog.rz-open {
        height: 90vh;
        height: 90dvh;
        max-height: 90vh;
        max-height: 90dvh;
        border-end-start-radius: 1rem;
        border-end-end-radius: 1rem;
    }

    /* ── 頁面專屬的手機版型改裝區 ────────────────────────────────────
       用法：頁面用 <查詢Grid_v1> 時多傳「額外Class」（值＝頁面專屬 class），
       Grid 外層就會多掛那個 class，新版型寫在這裡：
           .life-policy-grid.<頁面專屬class> …
       多一個 class＝特異度比共用規則（.life-policy-grid／.query-grid-v1）高一階，
       直接覆蓋即可，其他用同一個元件的 14 個頁面完全不受影響。
       可用的掛勾：Radzen reflow 的 .rz-data-grid.rz-datatable-reflow／
       .rz-data-row（一列＝一張卡片）／td > .rz-column-title（欄名）＋ .rz-cell-data（值）／
       明細展開列 tr.rz-expanded-row-content + .rz-expanded-row-template、
       本站自訂的 .grid-expand-icon（桌機箭頭）／.grid-expand-text（手機文字鈕）／
       .grid-footer-sum（合計欄）。
       目前掛勾：壽險保單查詢 → .life-policy-query（見 壽險保單查詢.razor），
       規則還沒寫，等新版型確定再填。 */
}
@media (min-width: 769px) {
    .test-cards-mobile {
        display: none;
    }
}

/* 明細展開區：寬度鎖在「看得見的 Grid 寬」，超出的在容器內橫向捲動。
   明細 td 撐滿主表全寬（主表 23 欄約 2000px，Grid 內部本來就會橫滑），
   沒有限寬的話明細跟著被撐寬（CDP 實測 1890px），窄視窗下直接被主表根
  （overflow:hidden）裁掉、連滑都沒得滑。
   用 container query 單位 cqw 鎖可見寬：不受側欄開合影響；不支援 cqw 的舊瀏覽器
   退回 max-width:100%（等於沒修）。桌機手機通用，正式頁＋測試頁一起修好。 */
.life-policy-grid .rz-data-grid-data {
    container-type: inline-size;
}
.life-policy-grid .rz-expanded-row-template {
    max-width: 100%;
    max-width: 100cqw;
    overflow-x: auto;
}

/* 明細展開列：主色淡 tint，跟資料列區隔。
   原生 --rz-grid-detail-template-background-color 在淺／深主題都只比列底深一點點，
   幾乎看不出來；這裡用 color-mix 以主題 primary 混色，深淺主題自動跟著走，
   結果是不透明色，文字維持主題字色，對比不受影響。 */
.life-policy-grid .rz-expanded-row-content > td,
.life-policy-grid .rz-expanded-row-template {
    background-color: color-mix(in srgb, var(--rz-primary) 14%, var(--rz-base-background-color));
}

/* 測試頁專用：8 個明細區塊「本體」（卡片自己）底色加深，不是後面的列。
   桌機是 Tab 裡的卡，手機是 .test-detail-tint 裡的卡；正式頁不動。 */
.test-grid-desktop .rz-expanded-row-content .rz-card,
.test-cards-mobile .test-detail-tint .rz-card {
    background-color: color-mix(in srgb, var(--rz-primary) 22%, var(--rz-base-background-color));
}

/* 壽險保單查詢主表（.life-policy-grid）。
   整頁捲軸不可行：Radzen 版面根（.rz-layout）本身 overflow:hidden，
   表格再寬也會被版面裁掉、出不了瀏覽器捲軸；所以 Grid 維持內部捲動，
   改以「次要欄預設隱藏＋顯示欄位挑選器」減少捲動需求。
   放 site.css 而不用 scoped css：Blazor Server 換頁走 SignalR 不換 <head>，
   scoped 指紋 URL 舊分頁吃不到；site.css URL 固定，重整即生效。 */

/* 過濾列各格自帶的 x 一律隱藏，改用過濾列首欄的清除鈕（一次清全部）。 */
.life-policy-grid .rz-cell-filter-clear {
    display: none;
}

/* Grid footer 合計列：吃主題原生的表尾 token（--rz-grid-foot-*），
   每套佈景主題（淺／深色）各自配好底＋字色，對比一定夠；
   之前用 --rz-primary 實底＋--rz-on-primary，深色主題會變成
   淺底＋白字（material-dark 實測 #bb86fc 底＋#fff 字），反而看不清。
   粗體＋主色頂線保留「合計列」醒目，頂線跟著主題主色走。 */
.life-policy-grid .rz-datatable-tfoot > tr > td {
    background-color: var(--rz-grid-foot-background-color);
    color: var(--rz-grid-foot-cell-color);
    font-weight: 700;
    /* 特異度 (0,2,2)：主題有條 .rz-grid-table tr:first-child > td{border-top:none}
       (0,2,2)，tfoot 只有一列永遠是 :first-child，不加 tr 會被它蓋掉（實測）。 */
    border-top: 2px solid var(--rz-primary);
}

/* 測試頁標題漏斗（RadzenSplitButton）：藏掉自帶的小三角箭頭，
   它跟主鈕（漏斗圖示，AlwaysOpenPopup）功能重複，留著礙眼。 */
.test-grid-desktop thead .rz-splitbutton .rz-splitbutton-menubutton {
    display: none;
}

/* 測試中選單項（壽險保單查詢測試）：文字吃主題警示色＋粗體，
   一眼看出還在測試；只在 Development 選單出現（見 MainLayout DevOnly 過濾）。
   RadzenPanelMenuItem 沒有 Style／class 參數，只能用 href 定位疊色；
   圖示色走原生 IconColor 參數（各 Profile 設 var(--rz-warning)）。 */
.rz-panel-menu a[href="/壽險保單查詢測試"] .rz-navigation-item-text {
    color: var(--rz-warning);
    font-weight: 700;
}

/* 數字過濾列的上下按鈕拿掉（RadzenNumeric 原生內建，過濾列自動產生的編輯器
   吃不到 ShowUpDown 參數，只能 CSS 藏）。 */
.life-policy-grid .rz-cell-filter .rz-numeric-button {
    display: none;
}

/* 欄位挑選器按鈕文字固定「欄位編輯器」：
   Radzen 下拉多選是寫死的 $"{已選數} {SelectedItemsText}" 格式（見 RadzenDropDown.razor），
   數字前綴參數消不掉，只能 CSS 藏原文、補固定字（hover 的 title 仍列出已選欄）。 */
.life-policy-grid .rz-column-picker .rz-dropdown-label {
    font-size: 0;
}

.life-policy-grid .rz-column-picker .rz-dropdown-label::after {
    content: "欄位編輯器";
    font-size: 0.875rem;
}

/* 過濾列的運算子按鈕（*A*、=、≠…）：文字藏起來，只留小漏斗圖示。
   按鈕 hover 照樣顯示中文運算子名稱（title）。 */
.life-policy-grid .rz-cell-filter .rz-filter-button {
    font-size: 0;
    padding: 0.15rem 0.2rem;
    min-width: 0;
}

.life-policy-grid .rz-cell-filter .rz-filter-button .rzi {
    font-size: 0.75rem;
    /* 原本繼承按鈕文字色，未聚焦時對比太低看不見；直接吃主題主色。 */
    color: var(--rz-primary);
}

/* 窄欄（<200px）Radzen 用 container query 把漏斗圖示 display:none 並改成
   浮貼式按鈕；這頁欄窄是常態，強制圖示顯示、按鈕回正常排版。 */
.life-policy-grid .rz-cell-filter-content .rz-filter-button .rzi {
    display: inline-block;
}

.life-policy-grid .rz-cell-filter-content .rz-filter-button {
    position: static;
    height: auto;
    max-height: none;
    line-height: normal;
}

.life-policy-grid .rz-cell-filter-content:has(.rz-filter-button) .rz-textbox {
    text-indent: 0;
}

/* 漏斗選單：各運算子原本的字元符號一律改用漏斗圖示，選單內只看中文名稱。 */
.life-policy-grid .rz-filter-menu-item .rz-filter-menu-symbol {
    font-size: 0;
}

.life-policy-grid .rz-filter-menu-item .rz-filter-menu-symbol::after {
    content: "filter_alt";
    font-family: "Material Symbols";
    font-size: 1rem;
    font-weight: 400;
    display: inline-block;
    line-height: 1;
    vertical-align: middle;
    color: var(--rz-primary);
}

/* ── 保單狀況 chip 自刻配色 ──────────────────────────────────────────
   用的地方：壽險保單查詢主清單（.life-policy-grid.life-policy-query）與
   壽險保單明細（.detail-body：明細彈窗不在 grid 裡面，所以不能只掛 grid 那條；
   展開列裡的明細同時符合兩者也不衝突 —— 值相同）。
   只改「長相」：選哪一色仍由資料庫的 Line推播類別決定（頁面只挑 ChipStyle）。

   為什麼要自刻：Radzen 主題的色票走淡彩（default：綠 #5dbf74／青 #2cc8c8／粉紅
   #f9777f），連實心（Shade.Default）都偏淡，擺在一整排資料裡不顯眼；官網那個
   看起來比較跳的版本是 Zen 付費主題的色票（免費套件沒有）。所以這裡自刻一組
   飽和色，白字對比都在 4.5:1 以上：綠＝已承保、藍＝受理中、紅＝契撤、灰＝對不到。

   RadzenChip 的 ChipStyle 只吃 BadgeStyle 列舉、沒有色票參數，只能 CSS 疊；
   選擇器三層 class，特異度高於主題的 .rz-chip-xxx.rz-shade-xxx（兩層）。
   要新增 Line推播類別時，在下面加一條對應色即可。 */
:is(.life-policy-grid.life-policy-query, .detail-body) .rz-chip.rz-chip-success {
    background-color: #2e7d32; /* 保單到達（承保） */
    color: #fff;
    font-weight: 600;
}

:is(.life-policy-grid.life-policy-query, .detail-body) .rz-chip.rz-chip-info {
    background-color: #1976d2; /* 受理中 */
    color: #fff;
    font-weight: 600;
}

:is(.life-policy-grid.life-policy-query, .detail-body) .rz-chip.rz-chip-danger {
    background-color: #d32f2f; /* 契撤（註銷） */
    color: #fff;
    font-weight: 600;
}

:is(.life-policy-grid.life-policy-query, .detail-body) .rz-chip.rz-chip-light {
    background-color: #546e7a; /* 對不到分類／沒值 */
    color: #fff;
    font-weight: 600;
}

/* 純狀態標籤不是按鈕：拿掉 RadzenChip 預設的「手指」游標與 hover 變暗
   （否則看起來像可以點）。元件本身的 role=button 是 RadzenChip 內建、沒參數可關。 */
:is(.life-policy-grid.life-policy-query, .detail-body) .rz-chip:not(.rz-state-disabled) {
    cursor: default;
}

:is(.life-policy-grid.life-policy-query, .detail-body) .rz-chip:not(.rz-state-disabled):hover {
    filter: none;
}

/* ── 查詢結果統計（壽險保單查詢：「共 N 筆／主約合計／附約合計／總保費合計」）──
   字級與粗體走元件參數（RadzenText TextStyle=H5），這裡只處理「擠壓」：
   這些統計在原生 RadzenStack 裡是 flex item，預設 flex-shrink:1，寬度不夠時
   會被壓成一條細長條、nowrap 的文字直接從兩邊被裁掉（手機實測「共 13 筆」
   只剩「筆」、三個標籤全不見）。
   給 flex:0 0 auto＋nowrap＝不壓縮、不折行，配 Stack 的 Wrap，裝不下時整個
   項目換到下一列（手機第二列會變一項一列），不會擠成兩行。
   掛在 .policy-summary 底下，其他頁的統計列不受影響（要套用時再加同一個 class）。 */
.policy-summary .policy-summary-item {
    flex: 0 0 auto;
    white-space: nowrap;
    font-weight: 700;
}

/* ── 明細書籤導覽（明細書籤導覽.razor：明細最上方的 Tabs 目錄）──
   桌機不顯示（.detail-nav 的 display:none）：桌機明細一律走彈窗，由下面
   .detail-popup-uniform-dialog 把那排導覽打開；沒有導覽的明細（產險保單、
   來佣率）桌機彈窗內容自己捲，也不會用到這排。
   手機卡片很長、彈窗裡要滑很久，這排就是書籤目錄（點一顆跳過去）。
   壽險保單查詢、照會單資料查詢兩頁共用（卡片掛 .detail-card）。

   手機版把它做成「標題列下方的固定一條」，不是浮在內容上的 sticky：
   明細彈窗的 .rz-dialog-content 不捲動（捲動交給 .detail-cards），
   版面切成 導覽列／卡片捲動區 兩塊，卡片就只會在導覽列下面那塊裡滑，
   不會有文字從導覽列底下穿過去（sticky 做法實測會留一條 20px 的內距縫，
   捲動時文字就從那裡冒出來）。卡片要讓開多少高度由 JS 量測（js/site.js）。

   兩塊式版面只在「有書籤導覽的明細」上用：用 :has(.detail-body) 認 ——
   沒有這條導覽的明細（產險保單明細、商品來佣率明細）維持「對話框內容自己捲、
   吃原本的內距」，不會被這條改到。 */
.detail-nav {
    display: none;
}

@media (max-width: 768px) {
    .detail-nav {
        display: block;
        background-color: var(--rz-dialog-background-color, var(--rz-base-background-color));
    }

    /* 書籤導覽只是「目錄」：Tabs 裡沒有內容，空的面板區不要留白。 */
    .detail-nav .rz-tabview-panels {
        display: none;
    }

    /* 彈窗內距改由卡片區自己帶（原本 .rz-dialog-content 的 20px）：
       導覽列要從標題列正下方開始，不能卡一層內距。 */
    .detail-popup-dialog:has(.detail-body) .rz-dialog-content {
        display: flex;
        flex-direction: column;
        overflow: hidden;
        padding: 0;
    }

    /* 對話框內容 → 明細外框 → 明細根 → 卡片區：整條 flex 鏈都要能縮，
       不然內層高度被內容撐開，卡片區永遠沒有可捲高度（實測外框 2281px 撐爆
       758px 的對話框內容）。block 子項的 min-height:auto 是關鍵，一定要歸零。 */
    .detail-popup-dialog:has(.detail-body) .detail-popup {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
    }

    .detail-body {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
    }

    .detail-cards {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: 1rem;
    }
}

/* ── 明細彈窗桌機版（查詢Grid_v1：所有明細一律用彈窗開）──
   手機規則（≤768px 那段）原封不動；這裡給桌機補同款效果（使用者 2026-10-20 指定）：
   ① 對話框滿版寬、貼齊畫面最上方、高度 90vh —— 底下留一截看得到被遮暗的原頁面，
   下方圓角（內容溢出用 overflow:hidden 裁）。不是置中卡片。
   ② 「導覽列／卡片捲動區」兩塊式版面（跟手機同一套）。
   .detail-nav 平常桌機不顯示（.detail-nav 的 display:none），這裡用 dialog 的
   .detail-popup-uniform-dialog class 把它打開 —— 所有明細彈窗都帶這個 class，
   但只有內容裡真有 .detail-body（明細書籤導覽）的才看得到導覽列。
   版式規則跟手機那段一樣用 :has(.detail-body) 認（沒有書籤導覽的明細
   維持「內容自己捲、吃原本內距」，見下面 :not(:has(.detail-body)) 的補強）。
   桌機主題把 .rz-dialog 置中（absolute＋四邊 inset），要四個邊都歸零重排：
   top/left/right 貼齊、bottom 放掉、width 蓋回 100%（原本由 DialogOptions 給，
   主題會用 !important 鎖，跟手機那段一樣要 !important 壓）。 */
.rz-dialog-wrapper > .rz-dialog.detail-popup-dialog.detail-popup-uniform-dialog.rz-open {
    top: 0;
    bottom: auto;
    left: 0;
    right: 0;
    width: 100% !important;
    height: 90vh;
    height: 90dvh;
    max-height: 90vh;
    max-height: 90dvh;
    overflow: hidden;
    border-end-start-radius: 1rem;
    border-end-end-radius: 1rem;
}

.rz-dialog.detail-popup-uniform-dialog .detail-nav {
    display: block;
    background-color: var(--rz-dialog-background-color, var(--rz-base-background-color));
}

.rz-dialog.detail-popup-uniform-dialog .detail-nav .rz-tabview-panels {
    display: none;
}

.rz-dialog.detail-popup-uniform-dialog:has(.detail-body) .rz-dialog-content {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
}

.rz-dialog.detail-popup-uniform-dialog:has(.detail-body) .detail-popup {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.rz-dialog.detail-popup-uniform-dialog:has(.detail-body) .detail-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.rz-dialog.detail-popup-uniform-dialog:has(.detail-body) .detail-cards {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 1rem;
}

/* 沒有書籤導覽的明細（產險保單查詢／產險、壽險商品來佣率）：內容沒有 .detail-body
   那條兩塊式 flex 鏈，對話框又固定 90vh（overflow:hidden），不另外讓內容自己捲的話
   下半段會被裁掉；桌機、手機都補同一條（手機 90vh 那條規則在上面 ≤768px 區塊）。 */
.rz-dialog-wrapper > .rz-dialog.detail-popup-uniform-dialog:not(:has(.detail-body)) .rz-dialog-content {
    overflow-y: auto;
    min-height: 0;
}
