:root {
    --pw-primary:        #0D2845;
    --pw-primary-700:    #163B65;
    --pw-primary-50:     #E7ECF2;
    --pw-accent:         #FF6B00;
    --pw-accent-50:      #FFF1E5;
    --pw-success:        #00875A;
    --pw-warning:        #F59E0B;
    --pw-error:          #DE350B;
    --pw-info:           #0052CC;
    --pw-bg:             #F4F5F7;
    --pw-surface:        #FFFFFF;
    --pw-text:           #172B4D;
    --pw-text-muted:     #5E6C84;
    --pw-border:         #DFE1E6;
    --pw-mono:           'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    --pw-sans:           'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}

html, body {
    font-family: var(--pw-sans);
    background: var(--pw-bg);
    color: var(--pw-text);
    -webkit-font-smoothing: antialiased;
}

/* ===========================================================================
   MAUI Windows host — body flex column layout + ẩn scrollbar.
   Class "pw-host-windows" được MainLayout.razor add vào <html> + <body>
   khi IClientSettings.IsWindowsDesktop = true → rule này no-op trên Blazor
   Server / Android / iOS / Mac.

   1) Ẩn scrollbar: native title bar đã bị gỡ trong Platforms/Windows/App.xaml.cs,
      scrollbar bám phải còn lại làm UI industrial bị rối. Content vẫn scroll
      được bằng wheel/touchpad/keyboard.

   2) Flex column body: BlazorWebView trên Windows có bug — position:fixed
      element mất paint sau khi window minimize → restore (hoặc đôi khi sau
      alt-tab). Lý do: WebView2 reset compositor layer khi viewport size đổi
      0→max, fixed element không tự re-attach. Giải pháp triệt để: KHÔNG dùng
      position:fixed cho footer. Thay vào đó body làm flex column,
      .mud-layout flex:1 chiếm phần trên, .pw-status-footer là flex item cuối
      với position:static — footer luôn ở đáy mà không phụ thuộc viewport
      coordinate, sống sót qua mọi window state change.
   =========================================================================== */
html.pw-host-windows,
body.pw-host-windows {
    scrollbar-width: none;        /* Firefox + Chromium modern */
    -ms-overflow-style: none;     /* IE / Edge legacy */
}
html.pw-host-windows::-webkit-scrollbar,
body.pw-host-windows::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;                /* WebView2 (Chromium) + Safari */
}

/* Cấu trúc Blazor MAUI Hybrid: body > #app > [.mud-layout, .pw-status-footer].
   Flex container là #app (KHÔNG phải body — body chỉ có #app làm direct child).
   KHÔNG động vào MudLayout internal (Mud's CSS có nhiều rule đặc thù, dễ vỡ).
   Footer là sibling của MudLayout trong #app's flex column. */
body.pw-host-windows > #app {
    height: 100vh !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}
/* MudLayout fill phần lớn space — flex grow trong #app column.
   Đồng thời ép .mud-layout TỰ NÓ thành flex column (Mud default là
   position:relative + height:100%, KHÔNG flex) để .mud-main-content
   (flex:1 1 auto từ Mud) nhận được height bound → overflow-y:auto engage
   và scroll dọc hoạt động. */
body.pw-host-windows #app > .mud-layout {
    flex: 1 1 0 !important;
    min-height: 0 !important;
    display: flex !important;
    flex-direction: column !important;
}
/* Footer = flex item cuối. position:relative (KHÔNG static) để z-index có hiệu
   lực — phải đè lên MudDrawer (position:fixed, z-index 1100) vốn extends full
   height và sẽ che phần trái footer nếu z-index thấp hơn. Giữ z-index:1100
   khớp với original để stacking visual không đổi (drawer z-index cùng level,
   DOM order quyết định — footer ở sau trong DOM nên thắng). */
body.pw-host-windows #app > .pw-status-footer {
    position: relative !important;
    flex: 0 0 auto !important;
    bottom: auto !important;
    left: auto !important;
    right: auto !important;
    transform: none !important;
    will-change: auto !important;
    backface-visibility: visible !important;
    z-index: 1100 !important;
}
/* Bỏ padding-bottom:36px (Mud-main-content có rule chừa chỗ cho footer fixed cũ)
   — giờ footer là sibling thật, không che content.
   min-height:0 cho phép flex item shrink dưới content size → khi content tràn,
   overflow-y:auto (line ~106) engage và bảng/page tự cuộn dọc. */
body.pw-host-windows .mud-main-content {
    padding-bottom: 0 !important;
    min-height: 0 !important;
}

/* ===== Base scroll behavior cho .mud-main-content =====
   Default: overflow-y: auto → page cuộn nội bộ trong .mud-main-content khi content tràn.
   Áp dụng cho non-table pages (Settings, dashboard, form-only…). Pages có MudPaper bọc
   MudTable → auto-fill rule (line ~390+) override thành overflow:hidden trên Desktop/Tablet
   (≥600px) để bảng tự xử lý scroll trong khung, page không cuộn. Mobile (<600px) giữ
   overflow-y:auto → page cuộn tự nhiên kể cả với bảng.

   Scrollbar visible mảnh: Body/html đã `scrollbar-width: none` (line 46-54) — property này
   inherited nên .mud-main-content cũng ẩn theo → user không thấy affordance scroll +
   một số WebView2 build block luôn wheel-scroll khi scrollbar invisible. Override `thin`
   ở đây để hiện indicator. */
.mud-main-content {
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(13,40,69,0.25) transparent;
}
.mud-main-content::-webkit-scrollbar {
    width: 10px; height: 10px;
}
.mud-main-content::-webkit-scrollbar-thumb {
    background: rgba(13,40,69,0.25);
    border-radius: 5px;
    border: 2px solid transparent;
    background-clip: padding-box;
}
.mud-main-content::-webkit-scrollbar-thumb:hover {
    background: rgba(13,40,69,0.45);
    background-clip: padding-box;
    border: 2px solid transparent;
}
.mud-main-content::-webkit-scrollbar-track {
    background: transparent;
}

/* ===========================================================================
   Fix double-scrollbar trong MudSelect / MudAutocomplete / MudMenu popover.

   Nguyên nhân (MudBlazor 9.4): rule `.mud-popover .mud-list { max-height: inherit;
   overflow-y: auto }` làm mud-list scroll. Nhưng `.mud-list-padding` thêm 8+8=16px
   padding → tổng element height của mud-list = max-height + 16px → vượt cỡ
   wrapper popover → wrapper buộc phải scroll cùng → 2 scrollbar dọc cạnh nhau.

   (LƯU Ý: MudBlazor 9 KHÔNG có class .mud-popover-paper như các phiên bản
   trước — chỉ có .mud-picker-popover-paper cho date picker. Phải target
   .mud-popover trực tiếp.)

   Fix 3 lớp:
   1. `.mud-popover` ép overflow:hidden → wrapper popover không scroll (MudPopover.cs
      có thể set inline `overflow: auto` qua JS — !important đè được).
   2. `box-sizing: border-box` trên mud-list → max-height bao gồm padding nếu
      padding không thể loại được (defense in depth).
   3. Loại padding-top/bottom của `.mud-list-padding` bên trong popover → list
      không có chrome dôi ra. Item đầu/cuối sát mép popover, lấy thêm 16px
      chiều cao hữu ích → hiển thị thêm được 1-2 item. */
.mud-popover {
    overflow: hidden !important;
}
.mud-popover .mud-list {
    box-sizing: border-box !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}
.mud-popover .mud-list-padding {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* ===== Industrial mono-numeric utilities ===== */
.pw-num {
    font-family: var(--pw-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
    letter-spacing: -0.5px;
}
.pw-num-lg { font-family: var(--pw-mono); font-size: 28px; font-weight: 700; letter-spacing: -1px; }
.pw-num-xl { font-family: var(--pw-mono); font-size: 56px; font-weight: 700; letter-spacing: -2px; line-height: 1; }
.pw-num-xxl { font-family: var(--pw-mono); font-size: 96px; font-weight: 700; letter-spacing: -3px; line-height: 1; }

/* ===== Page header bar ===== */
/* Layout: icon | title-col (flex:1, min-width:0 cho phép truncate) | actions (flex-wrap khi hẹp).
   Actions có nhiều control → khi viewport hẹp sẽ rớt xuống dòng dưới THAY VÌ bóp title 3 dòng.

   Sticky bám dưới AppBar khi page-scroll. top:0 — KHÔNG phải top:appbar-height.
   Lý do: position:sticky đo top từ SCROLLPORT TOP (= mud-main-content's content edge
   sau padding-top), KHÔNG từ viewport top. MudBlazor đã set
   `.mud-main-content { padding-top: var(--mud-appbar-height) }` (≥600px) → scrollport
   top ĐÃ ngay dưới AppBar. Set top:appbar-height nữa sẽ tạo gap = appbar-height.
   z-index 3 — trên content + sticky table header (2), dưới sticky toolbar (4) và
   MudAppBar (~1100). */
.pw-page-header {
    position: sticky;
    top: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    padding: 10px 20px;
    background: var(--pw-surface);
    border-bottom: 1px solid var(--pw-border);
    margin: -16px -16px 12px -16px;
    box-shadow: 0 2px 4px rgba(13,40,69,0.06);
}
.pw-page-header > div[style*="flex:1"] {
    min-width: 200px;
}
.pw-page-header h1 {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: var(--pw-text);
    letter-spacing: -0.2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pw-page-header .pw-page-icon {
    width: 32px; height: 32px; border-radius: 6px;
    background: var(--pw-primary-50);
    color: var(--pw-primary);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}

/* ===== KPI tiles ===== */
.pw-kpi {
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-left: 4px solid var(--pw-primary);
    border-radius: 6px;
    padding: 16px 18px;
    transition: box-shadow 120ms;
}
.pw-kpi:hover { box-shadow: 0 4px 12px rgba(13,40,69,0.08); }
.pw-kpi.is-success { border-left-color: var(--pw-success); }
.pw-kpi.is-warning { border-left-color: var(--pw-warning); }
.pw-kpi.is-error   { border-left-color: var(--pw-error); }
.pw-kpi.is-info    { border-left-color: var(--pw-info); }
.pw-kpi.is-accent  { border-left-color: var(--pw-accent); }

.pw-kpi-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--pw-text-muted);
    margin-bottom: 6px;
}
.pw-kpi-value {
    font-family: var(--pw-mono);
    font-size: 32px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -1px;
    color: var(--pw-text);
}
.pw-kpi-trend { font-size: 12px; color: var(--pw-text-muted); margin-top: 4px; }

/* ===== Status pill ===== */
.pw-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 10px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    white-space: nowrap;
    flex-shrink: 0;
}

/* MudTable status cells: prevent the cell itself from wrapping the pill,
   so the column auto-sizes to fit the longest status. */
.mud-table-cell.pw-cell-status,
.mud-table-cell .pw-pill {
    white-space: nowrap;
}
.pw-pill::before {
    content: ""; width: 6px; height: 6px; border-radius: 50%;
    background: currentColor;
}
.pw-pill.is-pending  { background: #EBECF0; color: #5E6C84; }
.pw-pill.is-active   { background: #DEEBFF; color: #0747A6; }
.pw-pill.is-ok       { background: #E3FCEF; color: #006644; }
.pw-pill.is-warn     { background: #FFFAE6; color: #974F0C; }
.pw-pill.is-error    { background: #FFEBE6; color: #BF2600; }
.pw-pill.is-issued   { background: #FFEBCC; color: #974F0C; }
.pw-pill.is-consumed { background: #F4ECFF; color: #5E40A8; }

/* ===========================================================================
   Live status badge (OEE-style pulsing dot) — used by <LiveBadge> component.
   When IsLive=true, the dot is solid green with a halo ring that expands
   outward (1.6s loop) — strong "alive" signal at a glance. When offline,
   gray static dot, no animation.
   =========================================================================== */
.pw-live-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 3px 10px 3px 8px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    line-height: 1;
    white-space: nowrap;
}
.pw-live-badge.is-live    { background: #E3FCEF; color: #006644; }
.pw-live-badge.is-offline { background: #EBECF0; color: #5E6C84; }

.pw-live-badge .pw-live-dot {
    position: relative;
    width: 8px; height: 8px; border-radius: 50%;
    flex-shrink: 0;
}
.pw-live-badge.is-live    .pw-live-dot { background: #36B37E; }
.pw-live-badge.is-offline .pw-live-dot { background: #6B778C; }

/* Animated halo: a sibling absolute layer that expands + fades out repeatedly */
.pw-live-badge.is-live .pw-live-dot::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: #36B37E;
    animation: pw-live-pulse 1.6s ease-out infinite;
}
@keyframes pw-live-pulse {
    0%   { transform: scale(1);   opacity: 0.7; }
    70%  { transform: scale(2.6); opacity: 0;   }
    100% { transform: scale(2.6); opacity: 0;   }
}
/* Respect user motion preferences */
@media (prefers-reduced-motion: reduce) {
    .pw-live-badge.is-live .pw-live-dot::before { animation: none; }
}

/* ===== Status footer (system bar) ===== */
.pw-status-footer {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: 28px;
    background: var(--pw-primary);
    color: #BAC7D5;
    display: flex;
    align-items: center;
    padding: 0 16px;
    font-size: 12px;
    z-index: 1100;
    gap: 16px;
    white-space: nowrap;
    overflow: hidden;
}
.pw-status-footer .pw-stat {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 0 10px;
    height: 100%;
    border-right: 1px solid rgba(255,255,255,0.08);
    min-width: 0;
}
.pw-status-footer .pw-stat:first-child { border-left: 1px solid rgba(255,255,255,0.08); }
.pw-status-footer .pw-stat strong { color: #fff; font-weight: 600; }
.pw-status-footer .pw-dot {
    position: relative;
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.pw-status-footer .pw-dot.ok { background: #36B37E; }
.pw-status-footer .pw-dot.off { background: #6B778C; }

/* Animated pulsing halo cho dot API (.pw-dot.ok) — reuse keyframes pw-live-pulse */
.pw-status-footer .pw-dot.ok::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: #36B37E;
    animation: pw-live-pulse 1.6s ease-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .pw-status-footer .pw-dot.ok::before { animation: none; }
    .pw-status-footer .pw-dot.ok { box-shadow: 0 0 0 2px rgba(54,179,126,0.25); }
}

/* push content above fixed footer */
.mud-main-content { padding-bottom: 36px !important; }

/* Drawer (sidebar) cũng phải tránh footer fixed — nếu menu dài hơn viewport,
   các item cuối bị che. Set trực tiếp lên .pw-nav (NavMenu wrapper) thay vì
   selector MudBlazor internal vì class internal có thể đổi giữa các version. */
.pw-nav { padding-bottom: 40px !important; }

/* Sticky header — giữ tiêu đề cột bám đỉnh khi cuộn (page hoặc nội bộ bảng).
   Bám vào scroll-container gần nhất: với auto-fill mode → bám top của
   .mud-table-container; với page-scroll mode → bám top của .mud-main-content.
   Áp dụng cho mọi MudTable, kể cả trong dialog. */
.mud-table-head th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: #FAFBFC;
}

/* ===========================================================================
   AUTO-FILL MUDTABLE — Desktop/Tablet (≥600px)
   ===========================================================================
   Chiến lược: MudPaper bọc MudTable chiếm chính xác chiều cao còn lại của
   viewport (sau AppBar + footer + chrome PageHeader/stat-strip/toolbar) →
   page KHÔNG cần scroll dọc, chỉ bảng tự scroll nội bộ.

   Per-page override: gắn Style="--pw-table-h: calc(100vh - XYZpx)" trên MudPaper
   để tinh chỉnh offset chrome cụ thể của page đó (xem các razor file Inventory,
   Materials, Lots…). Default fallback 240px = AppBar 56 + footer 28 + PageHeader
   ~76 + MudContainer pa-4 padding bottom 16 + safety ~64.

   Opt-out: thêm class "pw-table-no-fill" trên MudPaper bọc bảng để page-scroll
   tự nhiên (vd báo cáo nhiều section, table chỉ là 1 phần).

   Yêu cầu: :has() (Chrome 105+, Firefox 121+, Safari 15.4+). MAUI WebView2
   (Chromium) đáp ứng. Mobile (<600px) → bypass, bảng grow tự nhiên, page scroll.

   Sticky PageHeader (top:0) vẫn được declare nhưng ở auto-fill mode page không
   scroll → sticky không activate → harmless. Ở mode page-scroll (no fill, hoặc
   mobile) sticky engage bình thường. */

@media (min-width: 600px) {
    /* Body-lock universal: html + body + mud-main-content đều lock overflow
       khi có MudTable fillable → page TUYỆT ĐỐI không scroll dọc trên cả
       Blazor Server (browser) và MAUI host.
       Lý do cần lock cả html+body cho Blazor Server: không có .pw-host-windows
       constraint trên #app, body scroll natural nếu content dài → cần explicit
       lock. Trên MAUI Windows đã có lock ở #app (line 62-67) nên rule này
       redundant nhưng harmless. */
    html:has(.mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill)),
    body:has(.mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill)) {
        overflow: hidden !important;
        height: 100vh !important;
    }
    .mud-main-content:has(.mud-paper:has(> .mud-table):not(.pw-table-no-fill)) {
        overflow: hidden;
    }

    /* MudPaper bọc bảng = explicit height từ --pw-table-h, flex column */
    .mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill) {
        height: var(--pw-table-h, calc(100vh - 240px));
        min-height: 240px;
        overflow: hidden;
        display: flex;
        flex-direction: column;
    }

    /* MudTable bên trong Paper = flex column fill */
    .mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill) > .mud-table {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
        background: transparent;
    }

    /* Scroll container chính — phần nội dung cuộn được */
    .mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill) > .mud-table > .mud-table-container {
        flex: 1 1 auto;
        min-height: 0;
        overflow: auto;
    }

    /* Toolbar / loading bar / pagination của MudTable không scroll cùng */
    .mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill) > .mud-table > .mud-table-loading,
    .mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill) > .mud-table > .mud-table-pagination,
    .mud-main-content .mud-paper:has(> .mud-table):not(.pw-table-no-fill) > .mud-table > .mud-table-toolbar {
        flex: 0 0 auto;
    }
}

/* ===========================================================================
   INDUSTRIAL DATA-PAGE COMPONENTS
   Tiêu chuẩn MES/SCADA enterprise (Honeywell/Aveva/Fiori-leaning):
   - Mật độ thông tin cao, header SHOUTING, numeric monospace right-aligned.
   - Action discipline: action chính nổi, action thứ cấp ẩn cho tới hover.
   - Status semantic chỉ qua StatusPill — không dùng màu nền nguyên dòng.
   =========================================================================== */

/* Stat strip ngang đầu trang — cảm giác "control room" với 4-6 metric tiles */
.pw-stat-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: 6px;
    margin-bottom: 12px;
    overflow: hidden;
}
.pw-stat-strip__item {
    padding: 10px 16px;
    border-right: 1px solid var(--pw-border);
    display: flex; flex-direction: column; gap: 2px;
}
.pw-stat-strip__item:last-child { border-right: none; }
.pw-stat-strip__label {
    font-size: 10px; font-weight: 600; letter-spacing: 0.8px;
    text-transform: uppercase; color: var(--pw-text-muted);
}
.pw-stat-strip__value {
    font-family: var(--pw-mono); font-size: 22px; font-weight: 700;
    line-height: 1.1; letter-spacing: -0.5px; color: var(--pw-text);
}
.pw-stat-strip__hint {
    font-size: 11px; color: var(--pw-text-muted);
}
.pw-stat-strip__item.is-success .pw-stat-strip__value { color: var(--pw-success); }
.pw-stat-strip__item.is-warning .pw-stat-strip__value { color: var(--pw-warning); }
.pw-stat-strip__item.is-error   .pw-stat-strip__value { color: var(--pw-error); }
.pw-stat-strip__item.is-muted   .pw-stat-strip__value { color: var(--pw-text-muted); }

/* Industrial toolbar — search + filter chips inline, actions phải */
.pw-toolbar {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: 6px;
    padding: 8px 12px;
    margin-bottom: 12px;
}
.pw-toolbar__search { flex: 1 1 280px; min-width: 220px; }
.pw-toolbar__divider {
    width: 1px; height: 24px; background: var(--pw-border); margin: 0 4px;
}
.pw-toolbar__filters {
    display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
}

/* Modifier — toolbar sticky dán dưới MudAppBar (hoặc dưới PageHeader sticky nếu cùng page).
   Dùng cho multi-section reports (ShiftReport, OverrideReport, LossAnalytics…) khi
   page-scroll dài, filter context (ngày/ca/khu vực) cần luôn nhìn thấy được.
   top:0 — đo từ scrollport top (mud-main-content content edge, ngay dưới AppBar).
   z-index: 4 — trên content + sticky PageHeader (3) + table header (2), dưới
   MudAppBar (~1100). Box-shadow nhẹ để phân biệt với content cuộn dưới. */
.pw-toolbar.pw-toolbar--sticky {
    position: sticky;
    top: 0;
    z-index: 4;
    box-shadow: 0 2px 4px rgba(13,40,69,0.06);
}

/* Filter cell — wrapper cho từng MudSelect/MudTextField/MudDatePicker trong .pw-toolbar.
   Desktop: tôn trọng inline style (flex-basis, max-width) → fields cạnh nhau grow đều.
   Mobile (≤600px): ép full-width 1 field/row để dễ đọc/thao tác trên màn hình hẹp.
   Dùng !important để override max-width inline (vd 320/380/420px). */
.pw-filter-cell { min-width: 0; }
@media (max-width: 600px) {
    .pw-filter-cell {
        flex: 1 1 100% !important;
        max-width: none !important;
    }
}

/* Filter chip — toggle dạng segment, click chọn 1 trong nhiều */
.pw-filter-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 10px;
    border: 1px solid var(--pw-border);
    border-radius: 14px;
    background: var(--pw-surface);
    color: var(--pw-text-muted);
    font-size: 12px; font-weight: 500;
    cursor: pointer;
    transition: all 100ms;
    user-select: none;
    line-height: 1.4;
}
.pw-filter-chip:hover {
    background: var(--pw-primary-50);
    border-color: var(--pw-primary);
    color: var(--pw-primary);
}
.pw-filter-chip.is-active {
    background: var(--pw-primary);
    border-color: var(--pw-primary);
    color: #fff;
}
.pw-filter-chip__dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: currentColor; flex-shrink: 0;
}
.pw-filter-chip__count {
    font-family: var(--pw-mono); font-size: 11px; font-weight: 600;
    padding: 0 6px; border-radius: 8px;
    background: rgba(0,0,0,0.06);
}
.pw-filter-chip.is-active .pw-filter-chip__count {
    background: rgba(255,255,255,0.18);
}

/* Industrial data-table wrapper — dùng class này trên MudPaper bọc bảng để
   override styles bên trong. */
.pw-table-industrial .mud-table-head th {
    text-transform: uppercase;
    letter-spacing: 0.6px;
    font-size: 11px;
    font-weight: 700;
    color: var(--pw-text-muted);
    background: #FAFBFC !important;
    border-bottom: 2px solid var(--pw-border) !important;
    padding: 8px 12px;
}
.pw-table-industrial .mud-table-body td {
    font-size: 13px;
    padding: 6px 12px;
    border-bottom: 1px solid #EBECF0;
}
.pw-table-industrial .mud-table-body tr:nth-child(even) td {
    background: #FCFCFD;
}
.pw-table-industrial .mud-table-body tr:hover td {
    background: #F4F8FE !important;
}
.pw-table-industrial .pw-row-actions {
    opacity: 1;
    display: inline-flex; gap: 4px;
}

/* Cell helpers — chuẩn industrial: numeric mono right-align, code bold, muted secondary */
.pw-cell-num   { font-family: var(--pw-mono); font-variant-numeric: tabular-nums;
                  text-align: right; white-space: nowrap; }
.pw-cell-code  { font-family: var(--pw-mono); font-weight: 700; letter-spacing: -0.2px; }
.pw-cell-muted { color: var(--pw-text-muted); font-style: italic; }
.pw-cell-sub   { display: block; font-size: 11px; color: var(--pw-text-muted);
                  margin-top: 2px; line-height: 1.3; }

/* Empty state — không hiển thị card trống mà có hình & action */
.pw-empty {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 48px 24px;
    text-align: center;
    color: var(--pw-text-muted);
}
.pw-empty__icon {
    width: 56px; height: 56px; border-radius: 50%;
    background: var(--pw-primary-50); color: var(--pw-primary);
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 16px;
}
.pw-empty__title {
    font-size: 14px; font-weight: 600; color: var(--pw-text);
    margin-bottom: 4px;
}
.pw-empty__hint { font-size: 12px; max-width: 360px; line-height: 1.5; }

/* Group color dot — thay cho chip nền màu rộng, nhỏ hơn = ít noise */
.pw-color-dot {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    margin-right: 6px; vertical-align: middle;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.08) inset;
}

/* Pager footer chuẩn — MudPagination + info "Trang X/Y · Z dòng".
   Dùng thay MudTablePager mặc định, đồng bộ visual giữa mọi page. */
.pw-pager {
    padding: 8px 16px;
    border-top: 1px solid var(--pw-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    flex-shrink: 0;
    background: #FAFBFC;
}
.pw-pager__info {
    font-size: 12px;
    color: var(--pw-text-muted);
}
.pw-pager__info strong {
    color: var(--pw-text);
    font-weight: 700;
}

/* ===========================================================================
   INDUSTRIAL DIALOG COMPONENTS
   Dialog là form/viewer/confirm — không cần stat strip rộng, nhưng cần:
   - Section grouping với uppercase caption (chuẩn nhập liệu công nghiệp)
   - Meta info row (label-value pairs) ở đầu viewer
   - Info card có header bar (giống Settings)
   =========================================================================== */

/* Section grouping inside a form — uppercase caption + body */
.pw-form-section {
    margin-bottom: 16px;
}
.pw-form-section + .pw-form-section {
    padding-top: 14px;
    border-top: 1px solid #EBECF0;
}
.pw-form-caption {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--pw-text-muted);
    margin-bottom: 8px;
    display: flex; align-items: center; gap: 6px;
}
.pw-form-caption .mud-icon-root { color: var(--pw-primary); }

/* Helper text industrial — nhỏ, italic, muted (đã có trong nhiều chỗ) */
.pw-form-hint {
    font-size: 11px;
    color: var(--pw-text-muted);
    margin-top: 4px;
    line-height: 1.4;
}

/* Meta row at top of viewer dialogs — grid label/value để info dày đặc */
.pw-dialog-meta {
    background: #FAFBFC;
    border: 1px solid var(--pw-border);
    border-radius: 6px;
    padding: 12px 16px;
    margin-bottom: 14px;
}
.pw-dialog-meta__grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 6px 16px;
    font-size: 13px;
}
.pw-dialog-meta__label {
    font-size: 10px; font-weight: 600; letter-spacing: 0.6px;
    text-transform: uppercase; color: var(--pw-text-muted);
    align-self: center;
    white-space: nowrap;
}

/* Info card with header bar — chuẩn dùng trong Settings và detail dialogs */
.pw-info-card {
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: 6px;
    overflow: hidden;
    margin-bottom: 14px;
}
.pw-info-card__head {
    background: #FAFBFC;
    border-bottom: 1px solid var(--pw-border);
    padding: 10px 14px;
}
.pw-info-card__title {
    font-size: 12px; font-weight: 600; color: var(--pw-text);
    display: flex; align-items: center; gap: 6px;
}
.pw-info-card__sub {
    font-size: 10px; color: var(--pw-text-muted); letter-spacing: 0.4px;
    text-transform: uppercase; margin-top: 2px;
}
.pw-info-card__body { padding: 12px 14px; }

/* Action footer alert — banner nhẹ trong dialog (delta khi đổi giá trị) */
.pw-dialog-banner {
    font-size: 12px;
    padding: 8px 12px;
    border-radius: 4px;
    border: 1px solid;
    margin-top: 10px;
    line-height: 1.5;
}
.pw-dialog-banner.is-info    { background:#DEEBFF; border-color:#B3D4FF; color:#0747A6; }
.pw-dialog-banner.is-warning { background:#FFFAE6; border-color:#FFE380; color:#974F0C; }
.pw-dialog-banner.is-error   { background:#FFEBE6; border-color:#FFBDAD; color:#BF2600; }
.pw-dialog-banner.is-success { background:#E3FCEF; border-color:#ABF5D1; color:#006644; }

/* ===========================================================================
   INDUSTRIAL TAB STRIP — rolled by hand thay MudTabs để control kỹ hơn.
   - Underline accent navy, không có animation slide
   - Item disabled = grey + not-allowed
   - Compact, fit chuẩn "control panel"
   =========================================================================== */
.pw-tab-strip {
    display: flex;
    background: var(--pw-surface);
    border-bottom: 1px solid var(--pw-border);
    flex-wrap: wrap;
}
.pw-tab-strip__item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 18px;
    font-size: 13px;
    font-weight: 600;
    color: var(--pw-text-muted);
    background: transparent;
    border: 0;
    border-bottom: 3px solid transparent;
    cursor: pointer;
    transition: all 120ms;
    letter-spacing: 0.2px;
    margin-bottom: -1px;
    user-select: none;
    line-height: 1.2;
    font-family: inherit;
}
.pw-tab-strip__item:hover:not(:disabled):not(.is-active) {
    color: var(--pw-text);
    background: rgba(13, 40, 69, 0.04);
}
.pw-tab-strip__item.is-active {
    color: var(--pw-primary);
    border-bottom-color: var(--pw-primary);
}
.pw-tab-strip__item:disabled {
    color: #B3BAC5;
    cursor: not-allowed;
}
.pw-tab-strip__badge {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 10px;
    background: rgba(0,0,0,0.06);
    font-family: var(--pw-mono);
    font-size: 11px;
    font-weight: 700;
}
.pw-tab-strip__item.is-active .pw-tab-strip__badge {
    background: var(--pw-primary);
    color: #fff;
}
.pw-tab-strip__panel {
    padding: 18px 0;
}

/* ===========================================================================
   VERSION CARD — collapsible card cho recipe versions, lot history…
   - Header bar có badge + meta info
   - Active state = border-left navy stripe
   - Hover = subtle elevation
   =========================================================================== */
.pw-version-card {
    border: 1px solid var(--pw-border);
    border-radius: 6px;
    margin-bottom: 10px;
    overflow: hidden;
    background: var(--pw-surface);
    transition: border-color 120ms, box-shadow 120ms;
}
.pw-version-card:hover {
    border-color: var(--pw-primary);
    box-shadow: 0 1px 3px rgba(13,40,69,0.06);
}
.pw-version-card.is-active {
    border-left: 3px solid var(--pw-success);
}
.pw-version-card__head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    background: #FAFBFC;
    cursor: pointer;
    flex-wrap: wrap;
    border-bottom: 1px solid transparent;
    transition: background 100ms;
}
.pw-version-card__head:hover { background: #F4F5F7; }
.pw-version-card.is-expanded .pw-version-card__head { border-bottom-color: var(--pw-border); }
.pw-version-card__title {
    font-family: var(--pw-mono);
    font-size: 14px;
    font-weight: 700;
    color: var(--pw-text);
    letter-spacing: -0.2px;
    white-space: nowrap;
}
.pw-version-card__meta {
    display: flex;
    gap: 16px;
    font-size: 12px;
    color: var(--pw-text-muted);
    flex-wrap: wrap;
    align-items: center;
}
.pw-version-card__meta strong { color: var(--pw-text); font-weight: 600; }
.pw-version-card__expand {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--pw-text-muted);
    font-size: 12px;
}
.pw-version-card__body {
    padding: 16px;
}

@media (max-width: 599.98px) {
    .pw-version-card__meta { gap: 8px; flex-basis: 100%; }
    .pw-version-card__expand { margin-left: 0; flex-basis: 100%; justify-content: flex-end; }
}

/* ===========================================================================
   Responsive footer
   - Desktop  (≥ 1280px / lg): full layout, full date "Thứ tư, 29/04/2026"
   - Tablet   (960-1279px / md): rút gọn date, ẩn date dài
   - Small    (600-959px  / sm): ẩn user info (đã có ở appbar) và label phụ
   - Mobile   (< 600px    / xs): chỉ giữ API + Date short + Time
   =========================================================================== */

/* Mặc định: desktop hiện full date, ẩn short date */
.pw-status-footer .pw-stat-date-short { display: none; }

/* < 1280px (md trở xuống): đổi sang date ngắn, giảm gap để vừa */
@media (max-width: 1279.98px) {
    .pw-status-footer { gap: 8px; padding: 0 10px; }
    .pw-status-footer .pw-stat { padding: 0 8px; }
    .pw-status-footer .pw-stat-date-full { display: none; }
    .pw-status-footer .pw-stat-date-short { display: inline-flex; }
}

/* < 960px (sm/xs): ẩn user info (đã có ở popover account ở appbar) */
@media (max-width: 959.98px) {
    .pw-status-footer .pw-stat-user { display: none; }
}

/* ===========================================================================
   QR code SVG fit container.
   QRCoder.SvgQRCode generates SVG với width/height tuyệt đối (vd 246×246 cho
   payload 38 chars). Khi nhúng vào container nhỏ hơn (vd 180×180), SVG bị
   tràn/clip. Class này force SVG scale theo container, giữ tỷ lệ vuông.
   Quan trọng: container target phải đủ to (≥160px) để mỗi module hiển thị
   ≥4px — dưới mức này camera điện thoại không decode được QR.
   =========================================================================== */
.pw-qr-fit svg {
    width: 100% !important;
    height: 100% !important;
    display: block;
}

/* < 600px (xs/mobile): tối giản — API status + Date + Time */
@media (max-width: 599.98px) {
    .pw-status-footer { gap: 4px; padding: 0 6px; font-size: 11px; }
    .pw-status-footer .pw-stat { padding: 0 6px; gap: 4px; }
    .pw-status-footer .pw-stat-scale,
    .pw-status-footer .pw-stat-shift { display: none; }
    /* Ẩn các text phụ ("đã kết nối" / "thủ công"), chỉ giữ label + dot */
    .pw-status-footer .pw-stat-text { display: none; }
}

/* ===== Big weight readout ===== */
.pw-weight-display {
    background: linear-gradient(180deg, #0D2845 0%, #163B65 100%);
    color: #E0F2FE;
    border-radius: 12px;
    padding: 28px 32px;
    text-align: center;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06), 0 6px 20px rgba(13,40,69,0.18);
}
.pw-weight-display .pw-weight-label {
    font-size: 11px; font-weight: 600; letter-spacing: 1.2px;
    color: #8EC4F0; text-transform: uppercase;
}
.pw-weight-display .pw-weight-value {
    font-family: var(--pw-mono);
    font-size: 88px; font-weight: 700; line-height: 1;
    letter-spacing: -3px;
    color: #FFFFFF;
    text-shadow: 0 0 24px rgba(255,255,255,0.2);
}
.pw-weight-display .pw-weight-value.ok { color: #6BE7A1; text-shadow: 0 0 24px rgba(54,179,126,0.5); }
.pw-weight-display .pw-weight-value.warn { color: #FFAB00; text-shadow: 0 0 24px rgba(255,171,0,0.5); }
.pw-weight-display .pw-weight-value.error { color: #FF7452; text-shadow: 0 0 24px rgba(222,53,11,0.5); }
.pw-weight-display .pw-weight-uom {
    font-family: var(--pw-mono);
    font-size: 28px; font-weight: 600; color: #8EC4F0; margin-left: 8px;
}
.pw-weight-display .pw-weight-target {
    font-family: var(--pw-mono);
    font-size: 14px; color: #8EC4F0; margin-top: 8px;
    letter-spacing: 0.5px;
}

/* ===== Tolerance gauge ===== */
.pw-gauge {
    position: relative;
    height: 16px;
    border-radius: 8px;
    background: #EBECF0;
    overflow: hidden;
}
.pw-gauge .pw-gauge-band {
    position: absolute; top: 0; bottom: 0;
    background: rgba(0,135,90,0.18);
    border-left: 2px solid var(--pw-success);
    border-right: 2px solid var(--pw-success);
}
.pw-gauge .pw-gauge-marker {
    position: absolute; top: -2px; bottom: -2px;
    width: 3px; background: var(--pw-text);
    border-radius: 1px;
    box-shadow: 0 0 0 2px rgba(255,255,255,0.7);
}
.pw-gauge .pw-gauge-marker.ok    { background: var(--pw-success); }
.pw-gauge .pw-gauge-marker.warn  { background: var(--pw-warning); }
.pw-gauge .pw-gauge-marker.error { background: var(--pw-error); }

/* ===========================================================================
   INDUSTRIAL NAVIGATION MENU
   Phong cách: section header uppercase + nav item flat với navy stripe khi active.
   - Section "luôn mở" (Vận hành, Kho): chỉ là header text, không toggle
   - Section "có thể ẩn" (Master Data, Quality, Admin): có chevron + collapse
   - Active item: left navy stripe (chuẩn SCADA/MES) + bg navy nhạt
   =========================================================================== */
.pw-nav-industrial {
    font-family: var(--pw-sans);
    font-size: 13px;
    padding: 6px 0 0 0;
    /* Flex column với min-height đảm bảo nav fill drawer ngay cả khi parent
       không propagate height. Footer dùng margin-top:auto + position:sticky
       để dính đáy bất kể nav cuộn hay không. */
    display: flex;
    flex-direction: column;
    min-height: 100%;
}

/* ---- Section block (group of nav items) ---- */
.pw-nav-section {
    padding: 0;
    margin: 2px 0;
}
.pw-nav-section + .pw-nav-section {
    border-top: 1px solid #EBECF0;
    margin-top: 4px;
    padding-top: 6px;
}

/* Section header — uppercase label, optional toggle */
.pw-nav-section__head {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 10px 18px 6px 18px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--pw-text-muted);
    background: transparent;
    border: 0;
    line-height: 1.2;
    font-family: inherit;
    user-select: none;
    text-align: left;
}
.pw-nav-section__title { flex: 1; }
.pw-nav-section__head--toggle {
    cursor: pointer;
    transition: color 120ms;
}
.pw-nav-section__head--toggle:hover { color: var(--pw-text); }
.pw-nav-section__head--toggle:hover .mud-icon-root { color: var(--pw-text); }
.pw-nav-section__head .mud-icon-root {
    color: var(--pw-text-muted);
    transition: transform 150ms, color 120ms;
}
.pw-nav-section.is-expanded .pw-nav-section__head--toggle .mud-icon-root {
    transform: rotate(0deg);
}

/* ---- Nav item (single link) — indent 6px so với section head để rõ hierarchy ---- */
.pw-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 14px 7px 16px;
    margin: 1px 8px 1px 14px;
    border-radius: 5px;
    font-size: 13px;
    font-weight: 500;
    color: var(--pw-text);
    text-decoration: none;
    position: relative;
    transition: background 100ms, color 100ms;
    cursor: pointer;
    line-height: 1.4;
}
.pw-nav-item:hover {
    background: #F4F5F7;
    color: var(--pw-primary);
}
.pw-nav-item:hover .mud-icon-root {
    color: var(--pw-primary);
}
.pw-nav-item .mud-icon-root {
    color: var(--pw-text-muted);
    flex-shrink: 0;
    transition: color 100ms;
}
.pw-nav-item__text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Active state — left navy stripe + bg highlight (industrial signature) */
.pw-nav-item.active {
    background: var(--pw-primary-50);
    color: var(--pw-primary);
    font-weight: 600;
}
.pw-nav-item.active .mud-icon-root {
    color: var(--pw-primary);
}
.pw-nav-item.active::before {
    content: '';
    position: absolute;
    left: -2px;
    top: 5px;
    bottom: 5px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--pw-primary);
}

/* ---- Top item (Dashboard) — highlighted block ---- */
.pw-nav-item--top {
    margin: 6px 10px 10px 10px;
    padding: 10px 14px;
    font-weight: 600;
    font-size: 13.5px;
    background: linear-gradient(90deg, var(--pw-primary-50) 0%, rgba(231,236,242,0.4) 100%);
    border: 1px solid transparent;
}
.pw-nav-item--top:hover {
    background: var(--pw-primary-50);
    border-color: var(--pw-primary-50);
}
.pw-nav-item--top.active {
    background: var(--pw-primary-50);
    border-color: rgba(13,40,69,0.12);
}
.pw-nav-item--top.active::before {
    /* Top item dùng border thay stripe để tách bạch khỏi section items */
    display: none;
}

/* ---- Badge count (optional) ---- */
.pw-nav-item__badge {
    margin-left: auto;
    min-width: 22px;
    padding: 1px 7px;
    border-radius: 10px;
    background: rgba(0,0,0,0.06);
    font-family: var(--pw-mono);
    font-size: 11px;
    font-weight: 700;
    color: var(--pw-text-muted);
    text-align: center;
    line-height: 1.4;
    flex-shrink: 0;
}
.pw-nav-item__badge.is-warning {
    background: #FFFAE6;
    color: #974F0C;
}
.pw-nav-item__badge.is-error {
    background: #FFEBE6;
    color: #BF2600;
}
.pw-nav-item.active .pw-nav-item__badge {
    background: var(--pw-primary);
    color: #fff;
}

/* ---- Footer copyright — sticky bottom với scroll context là drawer ----
   margin-top:auto đẩy xuống đáy khi nav ngắn (flex column).
   position:sticky + bottom:0 giữ footer dính đáy khi drawer cuộn (nav dài). */
.pw-nav-industrial .pw-nav-footer {
    margin-top: auto;
    flex-shrink: 0;
    position: sticky;
    bottom: 0;
    padding: 10px 4px;
    border-top: 1px solid #EBECF0;
    background: #FFFFFF;
    font-size: 10px;
    color: var(--pw-text-muted);
    letter-spacing: 0.2px;
    text-align: start;
    line-height: 1.3;
    height: 60px;
}

/* ===== AppBar building blocks ===== */
.pw-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 4px 8px 4px 4px;
    border-radius: 8px;
    cursor: pointer;
    transition: background 120ms;
    user-select: none;
    outline: none;
    min-width: 0;          /* allow flex-shrink of brand text on small viewports */
}
.pw-brand:hover { background: rgba(255,255,255,0.06); }
.pw-brand:focus-visible { box-shadow: 0 0 0 2px rgba(255,255,255,0.4); }
.pw-brand-logo {
    width: 34px; height: 34px;
    border-radius: 7px;
    object-fit: contain;
    background: #FFFFFF;
    padding: 3px;
    flex-shrink: 0;
}
.pw-brand-text { line-height: 1.3; min-width: 0; }
.pw-brand-title {
    color: #fff;
    font-weight: 700;
    font-size: 15px;
    letter-spacing: 0.3px;
    line-height: 1.35;
    padding-bottom: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pw-brand-tagline {
    color: #8EC4F0;
    font-size: 11px;
    letter-spacing: 1.4px;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Hamburger — chỉ hiện ở tablet/mobile (< Md = 960px), desktop ẩn */
.pw-appbar-hamburger { display: none !important; margin-right: 4px; }

.pw-appbar-divider {
    width: 1px;
    align-self: stretch;
    margin: 10px 12px;
    background: rgba(255,255,255,0.12);
}

.pw-appbar-icons {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

/* Custom close button — chỉ render trên MAUI Windows (native title bar bị ẩn).
   Hover đỏ theo convention Windows (Segoe MDL2 caption button "Close"). */
.pw-appbar-close {
    margin-left: 8px;
}
.pw-appbar-close:hover {
    background-color: #E81123 !important;
    color: #FFFFFF !important;
}

/* ===========================================================================
   Responsive AppBar
   - Desktop  (≥ 1280px / lg): full layout
   - Tablet   (960-1279px / md): hide tagline, keep brand title + icons + full pill
   - Small    (600-959px  / sm): show hamburger, hide tagline, compact user pill
   - Mobile   (< 600px    / xs): show hamburger, hide brand text, hide print icon,
                                 ultra-compact user pill (avatar + arrow only)
   LƯU Ý CASCADE: base rule .pw-user-pill PHẢI đứng TRƯỚC các @media bên dưới
   — nếu đảo ngược, base rule (cùng specificity, source-order sau) sẽ override
   các override responsive của @media, gây lệch padding/background.
   =========================================================================== */

.pw-user-pill {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 4px 14px 4px 4px;
    background: rgba(255,255,255,0.08);
    border-radius: 999px;
    max-width: 280px;
    min-width: 0;
}

/* < 1280px: ẩn dòng tagline (quá dài cho tablet) */
@media (max-width: 1279.98px) {
    .pw-brand-tagline { display: none; }
}

/* < 960px (Md breakpoint của MudDrawer Responsive):
   Drawer chuyển sang Temporary → cần nút hamburger riêng */
@media (max-width: 959.98px) {
    .pw-appbar-hamburger { display: inline-flex !important; }
    .pw-appbar-divider { display: none; }
    .pw-user-pill { max-width: 200px; padding: 4px 10px 4px 4px; }
    .pw-user-name { max-width: 110px; font-size: 12px; }
    .pw-user-role { display: none; }    /* save vertical space */
}

/* < 600px: ultra-compact mobile */
@media (max-width: 599.98px) {
    .pw-appbar.mud-appbar > .mud-toolbar { padding-left: 6px; padding-right: 6px; }
    .pw-brand-title { display: none; }              /* logo only */
    .pw-brand { padding: 4px; gap: 0; }
    .pw-appbar-icon-print,
    .pw-appbar-icons .pw-appbar-icon-print { display: none; }
    .pw-user-pill {
        max-width: none;
        background: transparent;
        border: 1.5px solid rgba(255,255,255,0.35);
        padding: 0;
        gap: 0;
        width: 36px;
        height: 36px;
        box-sizing: border-box;
        justify-content: center;                    /* avatar nằm chính giữa khung tròn */
    }
    .pw-user-meta { display: none; }                /* avatar + arrow only */
    .pw-user-pill-arrow { display: none; }
}

.pw-user-avatar {
    width: 30px; height: 30px;
    background: var(--pw-accent);
    color: #fff;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 11.5px; font-weight: 700;
    letter-spacing: 0.4px;
    flex-shrink: 0;
}
.pw-user-meta { line-height: 1.3; min-width: 0; }
.pw-user-name {
    color: #FFFFFF;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    max-width: 210px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pw-user-role {
    color: #8EC4F0;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 1px;
    line-height: 1.4;
    text-transform: uppercase;
}
.pw-user-pill--clickable {
    cursor: pointer;
    transition: background 120ms;
}
.pw-user-pill--clickable:hover { background: rgba(255,255,255,0.14); }

/* ===== Account popover card ===== */
.pw-user-card {
    width: 320px;
    background: #FFFFFF;
}
.pw-user-card__head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    background: linear-gradient(135deg, #0D2845 0%, #163B65 100%);
    color: #fff;
}
.pw-user-card__name {
    font-size: 15px;
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 220px;
}
.pw-user-card__sub {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
    color: #BAC7D5;
    font-size: 11.5px;
}
.pw-user-avatar--lg {
    width: 44px !important;
    height: 44px !important;
    font-size: 15px !important;
    outline: 1.5px solid rgba(255,255,255,0.45);
    outline-offset: 2px;                            /* ring quanh avatar — đồng bộ style với pill ở appbar mobile */
}

.pw-user-card__rows { padding: 8px 0; }
.pw-user-card__row {
    display: grid;
    grid-template-columns: 24px 110px 1fr;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    font-size: 12.5px;
}
.pw-user-card__row + .pw-user-card__row { border-top: 1px dashed #EBECF0; }
.pw-user-card__row-label {
    font-size: 11px;
    color: #5E6C84;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    font-weight: 600;
}
.pw-user-card__row-val {
    text-align: right;
    color: #172B4D;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pw-user-card__foot {
    padding: 12px 16px 14px;
    border-top: 1px solid #EBECF0;
    background: #FAFBFC;
}

/* ===== AuditLog diff table ===== */
.pw-diff {
    border: 1px solid var(--pw-border);
    border-radius: 6px;
    overflow: hidden;
    font-size: 12.5px;
    background: var(--pw-surface);
}
.pw-diff__head {
    display: grid;
    grid-template-columns: 200px 1fr 1fr;
    background: #FAFBFC;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--pw-text-muted);
    border-bottom: 1px solid var(--pw-border);
}
.pw-diff__head > div { padding: 10px 14px; }
.pw-diff__col-old { border-left: 1px solid var(--pw-border); }
.pw-diff__col-new { border-left: 1px solid var(--pw-border); }

.pw-diff__row {
    display: grid;
    grid-template-columns: 200px 1fr 1fr;
    border-top: 1px solid #EBECF0;
}
.pw-diff__row:first-child { border-top: 0; }
.pw-diff__row.is-changed .pw-diff__cell--old { background: #FFF4F2; }
.pw-diff__row.is-changed .pw-diff__cell--new { background: #F0FBF5; }
.pw-diff__row:hover { background: #F4F5F7; }

.pw-diff__key {
    padding: 8px 14px;
    font-family: var(--pw-mono);
    font-size: 12px;
    color: var(--pw-text);
    font-weight: 600;
    background: #FAFBFC;
    border-right: 1px solid var(--pw-border);
    word-break: break-all;
}
.pw-diff__cell {
    padding: 8px 14px;
    font-family: var(--pw-mono);
    font-size: 12px;
    color: var(--pw-text);
    word-break: break-all;
    overflow-wrap: anywhere;
    white-space: pre-wrap;
    border-right: 1px solid #EBECF0;
    min-width: 0;
}
.pw-diff__cell:last-child { border-right: 0; }

/* ===== Mud overrides for industrial density ===== */
.mud-table-cell { font-size: 13px; }
.mud-table-head .mud-table-cell {
    font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.6px;
    color: var(--pw-text-muted);
    background: #FAFBFC;
}
.mud-paper { border: 1px solid var(--pw-border); }
.mud-button { text-transform: none; font-weight: 600; letter-spacing: 0.1px; }
.mud-appbar { border-bottom: 1px solid rgba(255,255,255,0.06); }

a, .btn-link { color: var(--pw-info); }
.content { padding-top: 1.1rem; }
h1:focus { outline: none; }

.valid.modified:not([type=checkbox]) { outline: 1px solid var(--pw-success); }
.invalid { outline: 1px solid var(--pw-error); }
.validation-message { color: var(--pw-error); }

.blazor-error-boundary {
    background: var(--pw-error);
    color: white;
    padding: 1rem 1rem 1rem 3.7rem;
}
.blazor-error-boundary::after { content: "An error has occurred." }

/* ===========================================================================
   Selected-row highlight for tables (Weighing line picker, etc.).
   Light blue tint + navy left stripe — strong "selected" cue while keeping
   dark text legible. Applied via RowClassFunc returning "pw-row-selected".
   =========================================================================== */
.pw-row-selected,
.pw-row-selected:hover,
.pw-row-selected td {
    background-color: #DEEBFF !important;       /* Atlassian-style light blue */
    box-shadow: inset 4px 0 0 0 #0052CC;        /* navy left stripe */
}
/* Bump material code/text contrast inside selected row */
.pw-row-selected td strong {
    color: #0D2845;                             /* deep navy — high contrast on light blue */
}

/* ===========================================================================
   Dialog styling — OEE look & feel áp dụng global cho tất cả MudDialog.
   Title bar xám nhạt với chữ đậm; body trắng padding rộng; footer xám với
   nút "Lưu" xanh lá, "Huỷ" text. Field bên trong dùng underline-only
   (label nhỏ phía trên, value đậm) thay cho khung outlined nặng nề.

   Opt-out: thêm class "pw-dialog-raw" lên <MudDialog Class="..."> để
   bỏ qua override (giữ style mặc định MudBlazor cho dialog đặc biệt).
   =========================================================================== */
.mud-dialog-container .mud-dialog:not(.pw-dialog-raw) {
    border-radius: 6px;
    overflow: hidden;
    box-shadow: 0 8px 32px rgba(13, 40, 69, 0.18);
}

/* Title bar — white background, bold dark navy text, thin full-width divider below. */
.mud-dialog:not(.pw-dialog-raw) > .mud-dialog-title,
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-title {
    position: relative;
    background: #FFFFFF;
    color: #0D2845;
    font-weight: 700;
    font-size: 16px;
    padding: 14px 48px 13px 18px;   /* extra right padding to clear the close button */
    border-bottom: 1px solid #E4E7EB;
    margin: 0;
    line-height: 1.3;
    letter-spacing: -0.1px;
}

/* ---- PwDialogHeader: icon chip + title + subtitle (đặt trong <TitleContent>) ---- */
.pw-dlg-head { display: flex; align-items: center; gap: 11px; min-width: 0; }
.pw-dlg-head__icon {
    flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; border-radius: 9px;
}
.pw-dlg-head__icon .mud-icon-root { font-size: 19px !important; }
.pw-dlg-head__text { min-width: 0; flex: 1; }
.pw-dlg-head__title {
    font: 700 16px Inter, sans-serif; color: #0D2845; letter-spacing: -0.1px; line-height: 1.25;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pw-dlg-head__sub {
    margin-top: 1px; font: 500 11.5px Inter, sans-serif; color: #5E6C84; letter-spacing: 0.1px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- Lỗi server inline trong form dialog (giữ dialog mở, rõ hơn snackbar thoáng qua) ---- */
.pw-dlg-error { margin-top: 12px; }

/* Close (X) button trong title bar — global MudDialogProvider CloseButton="true" */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-title .mud-button-root.mud-icon-button {
    position: absolute;
    top: 8px;
    right: 8px;
    color: #5E6C84;
    background: transparent;
}
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-title .mud-button-root.mud-icon-button:hover {
    color: #0D2845;
    background: #EBECF0;
}

/* Body */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content {
    background: #FFFFFF;
    padding: 18px 20px 20px 20px;
    color: #0D2845;
    /* Default MudBlazor: flex: 1 1 auto → content area grow để fill dialog height,
       gây empty space + ghost scrollbar khi content ngắn. Đổi sang 0 1 auto:
       không grow, chỉ shrink khi vượt max-height. Long-form dialog vẫn scroll OK
       vì max-height của parent dialog chặn ở calc(100vh - 96px). */
    flex: 0 1 auto;
}

/* Footer */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions {
    background: #F4F5F7;
    border-top: 1px solid #E4E7EB;
    padding: 12px 16px;
    gap: 8px;
}

/* "Lưu" / Primary filled button → xanh lá OEE */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions .mud-button-filled.mud-button-filled-primary {
    background-color: #1B7F4D;
    color: #FFFFFF;
    box-shadow: none;
    text-transform: none;
    font-weight: 600;
    padding: 6px 22px;
    border-radius: 4px;
}
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions .mud-button-filled.mud-button-filled-primary:hover {
    background-color: #166B40;
}

/* "Huỷ" / text button trong footer */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions .mud-button-text {
    color: #5E6C84;
    text-transform: none;
    font-weight: 500;
    padding: 6px 18px;
    background: transparent;
    border: 1px solid transparent;
}
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions .mud-button-text:hover {
    background: #EBECF0;
}

/* ---- Field style: outlined → underline-only bên trong dialog ---- */
/* Xoá viền outlined */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input.mud-input-outlined > .mud-input-outlined-border {
    border-width: 0 !important;
    border-bottom: 1px solid #DFE1E6 !important;
    border-radius: 0 !important;
    transition: border-color .15s;
}
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input.mud-input-outlined.mud-focused > .mud-input-outlined-border {
    border-bottom-color: #0052CC !important;
}
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input.mud-input-outlined.mud-input-error > .mud-input-outlined-border {
    border-bottom-color: #DE350B !important;
}
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input.mud-input-outlined .mud-input-slot {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* Label luôn ở vị trí "shrink" (phía trên) — tránh overlap với value */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-label-outlined {
    transform: translate(0, -6px) scale(.85) !important;
    background: transparent !important;
    padding: 0 !important;
    color: #5E6C84 !important;
    font-weight: 500;
}
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-label-outlined.mud-input-label-inputcontrol {
    left: 0 !important;
}

/* Value text trong field — đậm + dark navy giống OEE */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-slot input,
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-slot .mud-select-input input,
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-slot textarea {
    color: #0D2845;
    font-weight: 600;
    font-size: 14px;
}

/* Adornment icon (search/calendar/clock) — nhạt, không nổi */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-adornment .mud-icon-root {
    color: #5E6C84;
}

/* Spacing giữa các field cho thoáng */
.mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-control {
    margin-bottom: 4px;
}

/* ===========================================================================
   Weighing page — responsive layout
   - Desktop  (≥ 1280px / lg): full layout (88px weight, 280px station select)
   - Tablet   (960-1279px / md): slightly smaller weight readout, narrower select
   - Small    (600-959px / sm): wrap action stacks, single-column line panel
   - Mobile   (< 600px / xs): full-width selects/buttons, compact weight readout,
                              hide non-essential helper text, table h-scroll
   =========================================================================== */

/* Workstation select — default min-width on desktop, shrinks at tablet/mobile.
   MudSelect renders the class on its outer wrapper, so the width applies. */
.pw-weighing .pw-ws-select { min-width: 280px; flex: 0 1 320px; }

/* TextField with this class grows to fill the row on mobile (paste BatchId) */
.pw-weighing .pw-flex-grow { flex: 1 1 220px; }

/* Tablet — keep multi-column but tighten select width and weight digits */
@media (max-width: 1279.98px) {
    .pw-weighing .pw-ws-select { min-width: 220px; flex: 1 1 240px; }
    .pw-weighing .pw-weight-display { padding: 22px 24px; }
    .pw-weighing .pw-weight-display .pw-weight-value { font-size: 72px; letter-spacing: -2px; }
    .pw-weighing .pw-weight-display .pw-weight-uom { font-size: 24px; }
}

/* Small (tablet portrait / large phone) — stacks wrap, reduce paddings */
@media (max-width: 959.98px) {
    .pw-weighing .pw-ws-select { min-width: 200px; flex: 1 1 200px; }
    .pw-weighing .pw-weight-display { padding: 18px 18px; }
    .pw-weighing .pw-weight-display .pw-weight-value { font-size: 64px; letter-spacing: -2px; }
    .pw-weighing .pw-weight-display .pw-weight-uom { font-size: 22px; }
    /* Pack-breakdown banner — let lines wrap naturally instead of squeezing */
    .pw-weighing .mud-paper[style*="border-left:4px solid #FF6B00"] { font-size: 12px; }
    /* Line panel paper drops the 100% height when stacking under weight display */
    .pw-weighing .mud-grid-item .mud-paper[style*="height:100%"] { height: auto !important; }
    /* Lines table — slightly less max-height so action area stays reachable */
    .pw-weighing .pw-lines-scroll { max-height: 50vh !important; }
}

/* Mobile — full-width selects + buttons, ultra-compact weight readout */
@media (max-width: 599.98px) {
    .pw-weighing .pw-ws-select { min-width: 100%; flex: 1 1 100%; }
    .pw-weighing .pw-flex-grow { flex: 1 1 100%; }
    /* Batch-level action buttons (Cấp phát / Đã sử dụng / Xem đối chiếu) — stack full-width */
    .pw-weighing .pw-batch-actions .mud-button { flex: 1 1 100%; }
    .pw-weighing .pw-batch-actions .mud-spacer { display: none; }
    /* Weight display: cap digits so 4-decimal values don't overflow */
    .pw-weighing .pw-weight-display { padding: 16px 14px; border-radius: 8px; }
    .pw-weighing .pw-weight-display .pw-weight-value { font-size: 48px; letter-spacing: -1.5px; }
    .pw-weighing .pw-weight-display .pw-weight-uom { font-size: 18px; margin-left: 6px; }
    .pw-weighing .pw-weight-display .pw-weight-target { font-size: 11px; }
    .pw-weighing .pw-weight-display .pw-weight-label { font-size: 10px; letter-spacing: 0.8px; }
    /* Batch header strip — shrink the giant numbers a notch */
    .pw-weighing .mud-grid-item div[style*="font-size:18px"] { font-size: 16px !important; }
    /* Lines table: horizontal scroll on tiny viewports — forces operators to swipe
       the table instead of mashing all 7 columns into a 360px wide screen. */
    .pw-weighing .pw-lines-scroll { overflow-x: auto !important; max-height: 45vh !important; }
    .pw-weighing .pw-lines-scroll .mud-table { min-width: 720px; }
    /* Tighten the table-header toolbar: chips wrap below the title */
    .pw-weighing .mud-paper > div[style*="padding:14px 18px"] { padding: 10px 12px !important; }
    /* Slightly smaller table cells so more fits per row */
    .pw-weighing .mud-table-cell { font-size: 12px; padding: 8px 10px; }
}

/* ===========================================================================
   Version viewer (read-only panel inside RecipeEditorDialog) — responsive
   - The locked banner has icon + text + button. On desktop the button stays
     to the right; on narrow widths the row wraps and the button drops below
     the text. Without `min-width:0` on the text div, flex refuses to shrink
     and squeezes the text into a 1-character-wide column (the bug shown in
     the screenshot).
   - Meta grid: 4-up on desktop, 2-up on tablet, 1-up on mobile via auto-fit.
   - Stage tables (11 columns) scroll horizontally on small screens.
   =========================================================================== */
.pw-version-meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px 24px;
    font-size: 13px;
}

/* Stage table wrapper — allows horizontal scroll on tight viewports without
   forcing the meta grid (above) to also overflow. */
.pw-version-stage__table { overflow-x: auto; }
.pw-version-stage__table .mud-table { min-width: 720px; }

@media (max-width: 599.98px) {
    /* Cap the locked-banner button width so it can sit alongside text on tiny
       screens, and let it wrap below cleanly. The button itself never shrinks
       narrower than its label, so on phones we let it span the full row. */
    .pw-version-locked__btn { flex: 1 1 100%; }
    .pw-version-meta { gap: 8px 16px; grid-template-columns: repeat(2, 1fr); }
    .pw-version-stage__table { margin: 0 -12px; padding: 0 12px; }
}

/* ===========================================================================
   Recipe editor dialog — responsive layout
   - Desktop (≥ 960px): default min-height 600px, 2-col grid (xs=12 sm=6)
   - Tablet (600–959px): drop min-height, tabs may need icon-only
   - Mobile (<600px): full-screen-ish dialog, single-column form, compact tabs,
                       expansion-panel title wraps to multiple lines
   =========================================================================== */

/* Default: tall dialog so the user can see both tabs without resizing.
   Capped at viewport height by global mud-dialog rules. */
.pw-recipe-editor.mud-dialog { min-height: 600px; }

/* Fullscreen mode (DialogOptions.FullScreen=true): bắt content kéo dài hết
   chiều cao viewport, DialogActions pin xuống đáy. Không có rule này thì
   MudDialog render content theo natural height → footer "Đóng" nằm lưng chừng,
   bỏ phí diện tích trống bên dưới.
   Dùng chung cho mọi fullscreen dialog opt-in qua class "pw-fullscreen-pin". */
.pw-recipe-editor.mud-dialog-fullscreen,
.pw-batch-detail.mud-dialog-fullscreen {
    display: flex;
    flex-direction: column;
    height: 100vh;
    max-height: 100vh;
}
.pw-recipe-editor.mud-dialog-fullscreen .mud-dialog-content,
.pw-batch-detail.mud-dialog-fullscreen .mud-dialog-content {
    flex: 1 1 auto;
    overflow-y: auto;
}
.pw-recipe-editor.mud-dialog-fullscreen .mud-dialog-actions,
.pw-batch-detail.mud-dialog-fullscreen .mud-dialog-actions {
    flex: 0 0 auto;
    border-top: 1px solid var(--pw-border);
    background: #FAFBFC;
}

/* Version expansion-panel title — separators (· bullets) hidden on narrow
   screens because the row wraps and orphaned dots look worse than no dots. */
.pw-recipe-editor .pw-version-title .pw-sep { color: #5E6C84; font-size: 12px; }

/* Tablet — drop the 600px floor (small landscape tablets ~700px tall) */
@media (max-width: 959.98px) {
    .pw-recipe-editor.mud-dialog { min-height: 0; }
    /* Tabs with both icon + long text overflow at this width — let MudTabs scroll */
    .pw-recipe-editor .mud-tabs-toolbar { overflow-x: auto; }
    .pw-recipe-editor .mud-tab { min-width: 0; padding: 0 12px; }
}

/* Mobile — single column form, compact tabs, wrap version title */
@media (max-width: 599.98px) {
    /* Bump dialog to nearly full-screen (global flex max-height already chops at viewport) */
    .pw-recipe-editor.mud-dialog {
        margin: 8px !important;
        width: calc(100vw - 16px) !important;
        max-width: calc(100vw - 16px) !important;
    }
    /* Tighter tab content padding */
    .pw-recipe-editor .mud-tabs .mud-tab-panel.pa-4 { padding: 12px !important; }
    /* Tab labels — hide text on xs, keep icons (saves horizontal space) */
    .pw-recipe-editor .mud-tab .mud-tab-text-wrapper { font-size: 11px; }
    .pw-recipe-editor .mud-tab { padding: 0 8px; min-height: 44px; }
    /* Hide the · separators when the version-title row wraps — orphan dots */
    .pw-recipe-editor .pw-version-title .pw-sep { display: none; }
    /* Date range can be long ("Có hiệu lực từ dd/MM/yyyy đến dd/MM/yyyy") — let it
       break onto its own full-width line so the expand caret stays reachable. */
    .pw-recipe-editor .pw-version-title .pw-version-dates { flex-basis: 100%; }
    /* Form action button row — let "Đã lưu — chuyển sang tab..." caption wrap below */
    .pw-recipe-editor .mud-dialog-content .mud-typography-caption { flex-basis: 100%; }
}

/* ===========================================================================
   Print styles — workflow:
     PreWeight.printWithOrientation(landscape) trong App.razor:
       1. Clone .pw-print-area thành body-direct child #pw-print-clone
       2. Set body[data-printing] để rules dưới đây kích hoạt
       3. Inject @page rule cho orientation
       4. window.print() → cleanup
   Lý do clone: .pw-print-area gốc nằm sâu trong DOM (Routes > Layout > Page > ...),
   các ancestor có height layout dù visibility:hidden → in ra nhiều trang trắng.
   Đưa clone ra body level + display:none các sibling khác là cách duy nhất
   đảm bảo body height = đúng nội dung in.
   =========================================================================== */
@media print {
    /* Default page setup — JS sẽ inject @page rule riêng cho orientation */
    @page { size: A4 portrait; margin: 8mm; }

    html, body {
        margin: 0 !important; padding: 0 !important;
        background: white !important;
        height: auto !important; overflow: visible !important;
    }

    /* Khi đang print: ẩn mọi direct body child trừ clone */
    body[data-printing="true"] > *:not(#pw-print-clone) {
        display: none !important;
    }
    body[data-printing="true"] > #pw-print-clone {
        display: block !important;
        position: static !important;
        left: auto !important; top: auto !important;
        width: 100% !important; max-width: none !important;
        background: white !important;
        padding: 0 !important; margin: 0 !important;
        color: #000 !important;
    }
    #pw-print-clone table { page-break-inside: auto; }
    #pw-print-clone tr    { page-break-inside: avoid; }

    /* Print-only elements (vd chữ ký) hiển thị khi print */
    .pw-print-only { display: block !important; }
}

/* ===========================================================================
   GLOBAL RESPONSIVE POLISH — Desktop / Tablet / Mobile
   Áp dụng cho mọi trang qua các class dùng chung. Mục tiêu:
     - Desktop (≥1280px) : layout dày đặc, thông tin nhiều, table sticky-fill
     - Tablet  (600-1279): wrap toolbar, giảm padding, table rộng → h-scroll
     - Mobile  (<600px)  : near-fullscreen dialog, h-scroll table, touch ≥40px,
                            page-header subtitle xuống dòng (không truncate),
                            stat-strip thu gọn nhưng vẫn đọc được
   Gốc thiết kế: industrial/MES dày — màn nhỏ chấp nhận horizontal scroll cho
   bảng để giữ nguyên cột (operator quen layout) thay vì ẩn cột.
   =========================================================================== */

/* ---- Tablet (≤1279px): toolbar gap nhỏ hơn, tránh nút bị ép sát mép ---- */
@media (max-width: 1279.98px) {
    .pw-toolbar { gap: 8px; padding: 8px 10px; }
    .pw-stat-strip__item { padding: 10px 12px; }
    .pw-stat-strip__value { font-size: 20px; }
}

/* ---- Tablet portrait + small (≤959px) ---- */
@media (max-width: 959.98px) {
    /* KHÔNG can thiệp width/scroll cho .pw-table-industrial trên mobile.
       MudTable + browser tự xử lý layout — thêm min-width hoặc overflow-x ở
       outer wrapper sẽ tạo conflict (double scroll, cột bị crush, cell offset).
       Nếu page nào cần h-scroll riêng, dùng pattern .pw-lines-scroll như Weighing. */

    /* Page header: cho phép subtitle wrap thay vì truncate (ở desktop subtitle
       có ellipsis, mobile thì user cần đọc hết) */
    .pw-page-header { padding: 8px 14px; gap: 10px; }
    .pw-page-header h1 { font-size: 16px; }
    .pw-page-header > div[style*="flex:1"] { min-width: 140px; }
    .pw-page-header div[title] { white-space: normal !important; }

    /* Stat strip: 2 cols ổn định, viền phải bỏ ở dòng wrap (chỉ giữ separator
       trong cùng một dòng). border-right thường tạo viền lủng lẳng khi wrap. */
    .pw-stat-strip { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
    .pw-stat-strip__item { padding: 8px 12px; }
    .pw-stat-strip__value { font-size: 18px; }
    .pw-stat-strip__hint { font-size: 10px; }

    /* Pager — căn giữa khi flex-wrap để 2 dòng đẹp hơn (info trên, pagination dưới) */
    .pw-pager { justify-content: center; row-gap: 6px; }
    .pw-pager__info { flex: 1 1 100%; text-align: center; }

    /* Dialog tablet: rộng hơn để form thoáng (Mud's MaxWidth.Small ≈ 600px là
       OK cho tablet 600-959; chỉ tinh chỉnh margin và actions stack khi cần).
       Title/content padding giữ nguyên desktop để chuyên nghiệp. */
    .mud-dialog:not(.pw-dialog-raw):not(.mud-dialog-fullscreen) {
        margin: 16px !important;
        max-height: calc(100vh - 32px) !important;
    }
    /* Action button bự hơn cho ngón tay tap */
    .mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions .mud-button {
        min-height: 40px;
        padding: 8px 22px;
    }
}

/* ---- Mobile (≤599px): near-fullscreen dialog + touch target ≥40px ---- */
@media (max-width: 599.98px) {
    /* DIALOG MOBILE — chuẩn iOS/Material:
       - Near-fullscreen (margin 8px)
       - Flex column → title + actions sticky, content scroll giữa
       - Override min-width cứng trong DialogContent (nhiều dialog đặt 380-420px,
         tràn iPhone SE 375px)
       - Action buttons stack 2-cột (50% mỗi) để vừa ngón tay tap */
    .mud-dialog:not(.pw-dialog-raw):not(.mud-dialog-fullscreen) {
        margin: 8px !important;
        width: calc(100vw - 16px) !important;
        max-width: calc(100vw - 16px) !important;
        max-height: calc(100vh - 16px) !important;
        display: flex !important;
        flex-direction: column !important;
    }
    /* Title sticky + compact */
    .mud-dialog:not(.pw-dialog-raw) > .mud-dialog-title,
    .mud-dialog:not(.pw-dialog-raw) .mud-dialog-title {
        padding: 12px 44px 10px 16px !important;
        font-size: 14px !important;
        position: sticky;
        top: 0;
        z-index: 2;
        flex-shrink: 0;
    }
    .mud-dialog:not(.pw-dialog-raw) .mud-dialog-title .mud-button-root.mud-icon-button {
        top: 4px;
        right: 4px;
    }
    /* Content scroll nội bộ */
    .mud-dialog:not(.pw-dialog-raw) .mud-dialog-content {
        padding: 12px 16px !important;
        flex: 1 1 auto !important;
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch;
    }
    .mud-dialog-content > * { min-width: 0 !important; }
    /* Actions sticky bottom + stack 2-cột; nếu chỉ 1 button → full-width */
    .mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions {
        position: sticky;
        bottom: 0;
        z-index: 2;
        padding: 10px 12px !important;
        flex-shrink: 0;
        flex-wrap: wrap;
        gap: 8px;
    }
    .mud-dialog:not(.pw-dialog-raw) .mud-dialog-actions .mud-button {
        flex: 1 1 calc(50% - 4px);
        min-width: 0;
        min-height: 44px;
        padding: 8px 16px;
        font-size: 13px;
    }
    /* Spacing field trong dialog mobile — gọn hơn để tiết kiệm chiều cao */
    .mud-dialog:not(.pw-dialog-raw) .mud-dialog-content .mud-input-control {
        margin-bottom: 6px;
    }

    /* Page header: hiển thị 2 dòng (title + subtitle) chiếm full width,
       actions xuống dòng dưới. Reduce icon size cho gọn. */
    .pw-page-header { padding: 8px 12px; gap: 8px; }
    .pw-page-header .pw-page-icon { width: 28px; height: 28px; border-radius: 5px; }
    .pw-page-header h1 { font-size: 15px; }
    .pw-page-header > div[style*="display:flex"][style*="gap:8px"] {
        flex-basis: 100%;
        justify-content: flex-end;
    }

    /* Stat strip: 2 cột nhỏ gọn — value chính vẫn nổi bật */
    .pw-stat-strip { grid-template-columns: repeat(2, 1fr); }
    .pw-stat-strip__item:nth-child(2n) { border-right: none; }
    .pw-stat-strip__value { font-size: 17px; }

    /* Toolbar: search chiếm full row, các group action xuống dòng tự nhiên */
    .pw-toolbar { padding: 8px; gap: 6px; }
    .pw-toolbar__search { flex: 1 1 100%; }
    .pw-toolbar__divider { display: none; }
    .pw-filter-chip { padding: 6px 10px; font-size: 11px; }

    /* Touch target: MudIconButton Size.Small ≈ 32px → bump lên 40px tối thiểu
       cho mobile (chuẩn Apple HIG/Material). Áp cho row-actions trong table. */
    .pw-table-industrial .mud-icon-button-size-small,
    .pw-toolbar .mud-icon-button-size-small {
        min-width: 40px; min-height: 40px;
    }
    /* Checkbox cell trong table cũng phình ra cho dễ tap */
    .pw-table-industrial .mud-table-body .mud-checkbox { min-height: 40px; }

    /* MudTable mobile (small-device) mode — kích hoạt mặc định <600px qua
       Breakpoint=Xs. Mỗi <td> hiển thị flex row [data-label] ... [value].
       Polish card-style: cell có border-bottom rõ, label uppercase nhẹ,
       value phải bold. Padding mặc định MudBlazor 14/16px được giữ nguyên. */
    .pw-table-industrial .mud-table-body .mud-table-row {
        display: block;
        border: 1px solid var(--pw-border);
        border-radius: 6px;
        margin-bottom: 8px;
        background: var(--pw-surface);
        overflow: hidden;
    }
    .pw-table-industrial .mud-table-body .mud-table-cell {
        padding: 10px 14px !important;
    }
    .pw-table-industrial .mud-table-body .mud-table-cell:before {
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 0.4px;
        text-transform: uppercase;
        color: var(--pw-text-muted);
        flex-shrink: 0;
    }
    .pw-table-industrial .mud-table-body .mud-table-cell:not(:last-child) {
        border-bottom: 1px solid #EBECF0;
    }
    /* numeric cell: data-label trái, số phải — đã đúng default flex space-between */

    /* Pager: pagination control gọn lại, ẩn nút first/last để đỡ chật */
    .pw-pager .mud-pagination .mud-pagination-item:first-child,
    .pw-pager .mud-pagination .mud-pagination-item:last-child { display: none; }

    /* Empty state: padding nhỏ hơn cho mobile */
    .pw-empty { padding: 32px 16px; }
    .pw-empty__icon { width: 48px; height: 48px; margin-bottom: 12px; }

    /* AppBar dense layout — reduce icons gap để brand không bị đẩy */
    .pw-appbar-icons { gap: 0; }

    /* MudGrid item spacing trong dialog/page — giảm gutter cho khít */
    .mud-dialog-content .mud-grid { margin: -4px; }
    .mud-dialog-content .mud-grid > .mud-grid-item { padding: 4px; }
}

/* ---- Mobile portrait rất hẹp (≤375px / iPhone SE / mini) ----
   Ưu tiên các thông tin sống còn. Stat strip 1 cột để mỗi tile đủ rộng đọc số. */
@media (max-width: 375px) {
    .pw-stat-strip { grid-template-columns: 1fr; }
    .pw-stat-strip__item { border-right: none; border-bottom: 1px solid var(--pw-border); }
    .pw-stat-strip__item:last-child { border-bottom: none; }
    .pw-page-header h1 { font-size: 14px; }
}

/* ===========================================================================
   KIOSK WEIGHING SCREEN (.wx-*) — màn cân hợp nhất 1 mẻ / nhiều mẻ.
   Bố cục kiosk chuẩn PreWeight.Station: LCD navy LUÔN hiện (cân live), thước
   dung sai, hàng đợi sọc màu theo trạng thái, nút thao tác to. Dùng CHUNG cho
   PreWeight.Maui (có cân live qua ILiveScaleSource) và web admin (degrade về
   nhập tay khi không có nguồn cân). Token hoá theo --pw-* để đồng bộ toàn app.
   Component: Weighing.razor (trang) · WeighLcd.razor (LCD) · WeighQueue.razor.
   =========================================================================== */

/* --- Full-bleed: route cân chiếm trọn chiều cao (giống Station, không footer) ---
   MudContainer(pa-4) → bỏ padding; ẩn status footer 28px để canvas cao tối đa.
   :has() được WebView2/Edge (Maui) + Chrome/Edge (web) hỗ trợ. Nếu engine cũ
   không hỗ trợ → chỉ hụt vài px, không gãy chức năng. */
.mud-main-content:has(.wx) > .mud-container {
    padding: 0 !important;
    max-width: 100% !important;
}
body:has(.wx) .pw-status-footer { display: none !important; }

.wx {
    display: flex;
    flex-direction: column;
    gap: 10px;
    height: calc(100dvh - 56px);          /* trừ AppBar 56px */
    padding: 10px 12px;
    box-sizing: border-box;
    background: var(--pw-bg);
    overflow: hidden;
}

/* --- Top bar: trạm cân + chip mẻ + nút bao chẵn --- */
.wx-top {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: nowrap;
    padding: 8px 12px;
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(13, 40, 69, 0.04);
    flex-shrink: 0;
}
.wx-top__ws { flex-shrink: 0; min-width: 210px; }
.wx-top__chips {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    padding: 2px;
    scrollbar-width: thin;
}
.wx-chip {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px 6px 12px;
    min-height: 44px;
    background: var(--pw-bg);
    border: 1.5px solid var(--pw-border);
    border-radius: 10px;
    cursor: pointer;
    font-family: inherit;
    color: var(--pw-text);
    transition: all 0.12s ease;
}
.wx-chip:hover { border-color: #C9D3E0; }
.wx-chip.is-active {
    background: linear-gradient(135deg, #0D2845, #143A60);
    border-color: #0D2845;
    color: #FFFFFF;
}
.wx-chip__no { font: 700 13px var(--pw-mono); letter-spacing: 0.3px; }
.wx-chip__count {
    font: 700 10px var(--pw-sans);
    letter-spacing: 0.4px;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(13, 40, 69, 0.08);
    color: var(--pw-text-muted);
}
.wx-chip.is-active .wx-chip__count { background: rgba(255, 255, 255, 0.18); color: #FFFFFF; }
.wx-chip.is-done .wx-chip__count { background: #E3FCEF; color: #006644; }
.wx-chip__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px; height: 22px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: inherit;
    opacity: 0.55;
    cursor: pointer;
}
.wx-chip__close:hover { opacity: 1; background: rgba(0, 0, 0, 0.08); }
.wx-chip.is-active .wx-chip__close:hover { background: rgba(255, 255, 255, 0.14); }
.wx-wpp-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    min-height: 40px;
    background: var(--pw-surface);
    border: 1.5px solid #FFB07A;
    color: var(--pw-accent);
    border-radius: 10px;
    font: 700 12px var(--pw-sans);
    letter-spacing: 0.2px;
    cursor: pointer;
}
.wx-wpp-btn:hover { background: #FFF7EE; }

/* --- Stage: 2 cột (panel cân | hàng đợi) --- */
.wx-stage {
    flex: 1;
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(320px, 1fr);
    gap: 12px;
    min-height: 0;
}
.wx-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(13, 40, 69, 0.04);
    overflow: hidden;
}

/* --- Placeholder khi chưa có mẻ / chưa chọn dòng --- */
.wx-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 32px;
    text-align: center;
    color: var(--pw-text-muted);
}
.wx-empty__title { font: 700 16px var(--pw-sans); color: var(--pw-text); }
.wx-empty__sub { font-size: 13px; max-width: 360px; line-height: 1.5; }

/* --- Active panel: body cuộn + footer nút ghim --- */
.wx-active {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    padding: 16px;
    gap: 12px;
}
.wx-active__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.wx-active__body > * { flex-shrink: 0; }

.wx-mat { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.wx-mat__code {
    font: 800 13px var(--pw-mono);
    color: var(--pw-accent);
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 3px 9px;
    background: rgba(255, 107, 0, 0.08);
    border: 1px solid rgba(255, 107, 0, 0.30);
    border-radius: 6px;
    line-height: 1.2;
}
.wx-mat__name { font-size: 19px; font-weight: 800; color: var(--pw-primary); line-height: 1.2; }
.wx-mat__batch {
    margin-left: auto;
    font: 700 12px var(--pw-mono);
    color: var(--pw-text-muted);
    padding: 3px 8px;
    background: var(--pw-bg);
    border: 1px solid var(--pw-border);
    border-radius: 6px;
}

/* Scan gate — nhắc quét mã NL trước khi mở khoá cân */
.wx-scangate {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: #FFF7E6;
    border: 1px solid #FFD691;
    border-left: 4px solid #FF8B3D;
    border-radius: 8px;
    font: 700 13px var(--pw-sans);
    color: #6B4500;
}

/* Pack breakdown banner (bao chẵn vs lẻ) */
.wx-pack {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 14px;
    background: #FFF7E6;
    border: 1px solid #FFD691;
    border-left: 4px solid #FF8B3D;
    border-radius: 8px;
}
.wx-pack__title { font: 700 13px var(--pw-sans); color: #6B4500; line-height: 1.5; }
.wx-pack__title .wx-num { color: var(--pw-primary); font-family: var(--pw-mono); }
.wx-pack__loose { color: #B45309; }
.wx-pack__hint { font-size: 11px; color: #8A6D3B; margin-top: 3px; }

/* --- LCD navy (cân live) — port từ WeighDialog .pw-readout, phóng to kiosk 88px --- */
.wx-lcd {
    position: relative;
    background:
        radial-gradient(ellipse at 15% 0%, rgba(74, 222, 128, 0.05), transparent 50%),
        radial-gradient(ellipse at 85% 100%, rgba(0, 82, 204, 0.10), transparent 50%),
        linear-gradient(180deg, #0F2D4D 0%, #061629 100%);
    border: 1.5px solid #1A3958;
    border-radius: 14px;
    overflow: hidden;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.06),
        0 4px 16px rgba(0, 0, 0, 0.12);
    transition: border-color 0.2s, box-shadow 0.2s;
}
.wx-lcd.is-ok    { border-color: #4ADE80; box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.12), 0 8px 24px rgba(74, 222, 128, 0.14); }
.wx-lcd.is-under { border-color: #FFB07A; box-shadow: 0 0 0 3px rgba(255, 138, 61, 0.12), 0 8px 24px rgba(255, 138, 61, 0.12); }
.wx-lcd.is-over  { border-color: #FF6B6B; box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.14), 0 8px 24px rgba(255, 107, 107, 0.16); }

.wx-lcd__strip {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 7px 14px;
    background: rgba(0, 0, 0, 0.22);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    font: 700 11px var(--pw-sans);
    color: #C7D4E4;
}
.wx-lcd__led { width: 9px; height: 9px; border-radius: 50%; background: #475569; flex-shrink: 0; }
.wx-lcd__led.is-on { background: #4ADE80; box-shadow: 0 0 6px rgba(74, 222, 128, 0.85); }
.wx-lcd__led.is-off { background: #DE350B; box-shadow: 0 0 6px rgba(222, 53, 11, 0.8); }
.wx-lcd__dev { font-weight: 800; letter-spacing: 0.3px; color: #EAF1FA; }
.wx-lcd__state { opacity: 0.8; letter-spacing: 0.4px; text-transform: uppercase; }
.wx-lcd__stable {
    display: inline-flex; align-items: center; gap: 4px;
    font-weight: 800; letter-spacing: 0.6px; padding: 2px 9px; border-radius: 10px;
}
.wx-lcd__stable.is-stable { background: rgba(74, 222, 128, 0.20); color: #6BE7A1; }
.wx-lcd__stable.is-motion { background: rgba(255, 171, 0, 0.20); color: #FFC44D; }
.wx-zt {
    display: inline-flex; align-items: center; gap: 4px;
    background: rgba(255, 255, 255, 0.10);
    color: #DCE6F2;
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 7px;
    padding: 5px 12px;
    min-height: 30px;
    font: 800 11px var(--pw-sans);
    letter-spacing: 0.4px;
    cursor: pointer;
}
.wx-zt:hover:not(:disabled) { background: rgba(255, 255, 255, 0.18); }
.wx-zt:disabled { opacity: 0.4; cursor: default; }

.wx-lcd__head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 8px 16px 0;
    font: 800 10px var(--pw-sans);
    letter-spacing: 1.2px; text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
}
.wx-eval {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 10px; border-radius: 999px;
    font: 800 11px var(--pw-sans); letter-spacing: 0.6px; text-transform: uppercase;
}
.wx-eval.is-empty { background: rgba(255, 255, 255, 0.10); color: rgba(255, 255, 255, 0.6); }
.wx-eval.is-ok    { background: rgba(74, 222, 128, 0.18); color: #6BE7A1; }
.wx-eval.is-under { background: rgba(255, 171, 0, 0.18);  color: #FFC44D; }
.wx-eval.is-over  { background: rgba(255, 107, 107, 0.20); color: #FF8888; }

.wx-lcd__main {
    display: flex; align-items: baseline; justify-content: center; gap: 10px;
    padding: 4px 16px 6px;
}
.wx-lcd__value {
    font: 800 88px/1 var(--pw-mono);
    color: #B8C7D9;
    letter-spacing: -1px;
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 16px rgba(255, 255, 255, 0.08);
    transition: color 0.15s, text-shadow 0.15s;
}
.wx-lcd__value.is-empty { color: #4A6485; }
.wx-lcd__value.is-ok    { color: #6BE7A1; text-shadow: 0 0 24px rgba(111, 233, 160, 0.45); }
.wx-lcd__value.is-under { color: #FFB07A; text-shadow: 0 0 24px rgba(255, 176, 122, 0.35); }
.wx-lcd__value.is-over  { color: #FF8888; text-shadow: 0 0 24px rgba(255, 136, 136, 0.45); }
.wx-lcd__uom { font: 700 28px var(--pw-sans); color: #8EC4F0; }

.wx-lcd__targets {
    display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
    margin: 0 16px 12px;
    padding-top: 10px;
    border-top: 1px dashed rgba(255, 255, 255, 0.12);
}
.wx-lcd__t { text-align: center; }
.wx-lcd__t small {
    display: block; font: 800 9px var(--pw-sans); letter-spacing: 1px;
    color: rgba(255, 255, 255, 0.45); text-transform: uppercase; margin-bottom: 2px;
}
.wx-lcd__t strong {
    font: 700 17px var(--pw-mono); color: #DCE5F0;
    font-variant-numeric: tabular-nums;
}
.wx-lcd__t.is-target strong { color: #FFFFFF; }

/* --- Thước dung sai (gauge) --- */
.wx-gauge {
    position: relative; height: 26px; border-radius: 6px; overflow: hidden;
    background: #EDF2F7; border: 1px solid var(--pw-border);
    display: flex;
}
.wx-gauge__zone { position: absolute; top: 0; bottom: 0; }
.wx-gauge__zone--under { left: 0; background: rgba(245, 158, 11, 0.32); }
.wx-gauge__zone--ok    { background: rgba(0, 135, 90, 0.30); }
.wx-gauge__zone--over  { right: 0; background: rgba(222, 53, 11, 0.30); }
.wx-gauge__needle {
    position: absolute; top: -4px; bottom: -4px; width: 4px;
    background: var(--pw-primary); border-radius: 2px;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 2px 6px rgba(13, 40, 69, 0.4);
    transition: left 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    transform: translateX(-2px);
    z-index: 2;
}
.wx-gauge-scale {
    display: flex; justify-content: space-between;
    font: 700 10px var(--pw-mono); color: var(--pw-text-muted);
    margin-top: 4px;
}
.wx-gauge-scale__ok { color: var(--pw-success); }

/* --- Lot panel --- */
.wx-lot {
    padding: 10px 12px;
    background: linear-gradient(180deg, #F8FAFD, #F4F7FB);
    border: 1px solid var(--pw-border);
    border-left: 4px solid var(--pw-accent);
    border-radius: 10px;
}
.wx-lot--empty { background: #FFF8EC; border-color: #FFD691; border-left-color: #FF8B3D; }
.wx-lot__head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.wx-lot__title { font: 800 11px var(--pw-sans); letter-spacing: 0.5px; text-transform: uppercase; color: var(--pw-text-muted); }
.wx-lot__list { display: flex; flex-direction: column; gap: 4px; }
.wx-lot__row {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px; background: var(--pw-surface);
    border: 1px solid var(--pw-border); border-radius: 8px;
    font-size: 12px;
}
.wx-lot__seq { background: var(--pw-info); color: #FFF; padding: 1px 6px; border-radius: 4px; font: 700 10px var(--pw-mono); }
.wx-lot__no { font: 800 13px var(--pw-mono); color: var(--pw-primary); }
.wx-lot__remain {
    display: inline-flex; align-items: center; gap: 6px;
    margin-top: 8px; padding: 6px 10px;
    background: rgba(255, 107, 0, 0.10);
    border: 1px solid rgba(255, 107, 0, 0.30);
    border-radius: 8px;
    font: 800 11px var(--pw-sans); letter-spacing: 0.4px;
    color: var(--pw-accent); text-transform: uppercase;
}

/* --- Footer nút thao tác (ghim, không cuộn) --- */
/* ===== Footer action buttons — style port 1:1 từ PreWeight.Station (.wx-bigbtn) =====
   Ghost xám (Zero/Tare/vô hiệu) · CTA xanh (bắt đầu mẻ/quét lô/ghi cân/xác nhận) ·
   cam warning (GS duyệt) · nhãn IN HOA, icon 28px, nút chính rộng gấp đôi (1fr 1fr 2fr). */
.wx-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: 12px;
    flex-shrink: 0;
    padding-top: 2px;
}
/* Zero + Tare + nút chính → nút chính rộng gấp đôi, đúng bố cục Station */
.wx-actions--zt { grid-template-columns: 1fr 1fr 2fr; }
.wx-actions--secondary { display: flex; gap: 8px; flex-wrap: wrap; }
.wx-bigbtn {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 4px;
    min-height: 88px;
    padding: 12px;
    border-radius: 14px;
    border: 2px solid transparent;
    font: 800 17px var(--pw-sans);
    letter-spacing: 1.5px;
    text-transform: uppercase;
    cursor: pointer;
    transition: all 0.12s ease;
    text-align: center;
}
.wx-bigbtn .mud-icon-root { font-size: 28px !important; }
.wx-bigbtn__sub { font: 700 10px var(--pw-sans); letter-spacing: 1.2px; opacity: 0.85; text-transform: none; }
.wx-bigbtn:disabled { opacity: 0.45; cursor: not-allowed; transform: none !important; }
.wx-bigbtn--ghost { background: #F4F7FB; border-color: #DFE6EF; color: #0D2845; }
.wx-bigbtn--ghost:hover:not(:disabled) { background: #FFFFFF; border-color: #99B8DB; transform: translateY(-1px); }
.wx-bigbtn--zt { min-height: 88px; }
/* CTA chính (bắt đầu mẻ · quét/chọn lô · ghi số cân · xác nhận) — nền xanh sẵn-sàng của Station */
.wx-bigbtn--scan,
.wx-bigbtn--record,
.wx-bigbtn--confirm {
    background: linear-gradient(135deg, #4ADE80, #00875A);
    color: #FFFFFF;
    box-shadow: 0 6px 20px rgba(0, 135, 90, 0.35);
}
.wx-bigbtn--scan:hover:not(:disabled),
.wx-bigbtn--record:hover:not(:disabled),
.wx-bigbtn--confirm:hover:not(:disabled) {
    filter: brightness(1.06);
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(0, 135, 90, 0.45);
}
/* GS phê duyệt ngoại lệ vượt — cam warning của Station */
.wx-bigbtn--warning {
    background: linear-gradient(135deg, #FFB347, #F59E0B);
    color: #FFFFFF;
    box-shadow: 0 6px 20px rgba(245, 158, 11, 0.30);
}
.wx-bigbtn--warning:hover:not(:disabled) {
    filter: brightness(1.06);
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(245, 158, 11, 0.40);
}
/* Dòng đã chốt — nền xanh nhạt hoàn tất */
.wx-bigbtn--done { background: #E3FCEF; border-color: #ABF5D1; color: #006644; }

/* nút nhỏ trong body (thêm lot / cân lại / GS / tem) */
.wx-minibtn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 14px; min-height: 40px;
    border-radius: 9px; border: 1.5px solid var(--pw-border);
    background: var(--pw-surface); color: var(--pw-text);
    font: 700 12px var(--pw-sans); cursor: pointer;
}
.wx-minibtn:hover:not(:disabled) { border-color: #C9D3E0; }
.wx-minibtn:disabled { opacity: 0.45; cursor: not-allowed; }
.wx-minibtn--accent { border-color: #FFB07A; color: var(--pw-accent); }
.wx-minibtn--warn { border-color: #F5C36B; color: #974F0C; }

/* Nhập tay (web / mất kết nối cân) */
.wx-manual {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px;
    background: var(--pw-bg);
    border: 1px dashed var(--pw-border);
    border-radius: 10px;
}

/* --- Hàng đợi (cột phải) --- */
.wx-queue {
    display: flex; flex-direction: column;
    min-height: 0; height: 100%;
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(13, 40, 69, 0.04);
    overflow: hidden;
}
.wx-queue__head {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 10px 14px;
    border-bottom: 1px solid var(--pw-border);
    flex-shrink: 0;
}
.wx-queue__title { font: 800 12px var(--pw-mono); letter-spacing: 1.5px; color: var(--pw-primary); }
.wx-queue__sub { font: 700 11px var(--pw-sans); color: var(--pw-text-muted); }
.wx-seg {
    display: inline-flex; border: 1px solid var(--pw-border); border-radius: 8px; overflow: hidden;
}
.wx-seg__btn {
    padding: 5px 11px; border: none; background: var(--pw-surface);
    font: 700 11px var(--pw-sans); color: var(--pw-text-muted); cursor: pointer;
}
.wx-seg__btn.is-active { background: var(--pw-primary); color: #FFFFFF; }
.wx-queue__list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 8px; }

.wx-grp { margin: 6px 2px 2px; }
.wx-grp__head {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 6px;
    font: 800 11px var(--pw-sans); letter-spacing: 0.3px; color: var(--pw-text-muted);
    text-transform: uppercase;
}
.wx-grp__idx {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--pw-primary); color: #FFF; font: 800 11px var(--pw-mono);
}
.wx-grp__idx.is-done { background: var(--pw-success); }

.wx-line {
    position: relative;
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    padding: 10px 12px 10px 16px;
    margin: 6px 0;
    background: var(--pw-surface);
    border: 1.5px solid var(--pw-border);
    border-radius: 12px;
    text-align: left;
    cursor: pointer;
    transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    overflow: hidden;
}
.wx-line:hover { border-color: #C9D3E0; }
.wx-line.is-active {
    border-color: var(--pw-accent);
    background: linear-gradient(135deg, #FFF7F0 0%, #FFFFFF 60%);
    box-shadow: 0 0 0 3px rgba(255, 107, 0, 0.15), 0 4px 12px rgba(255, 107, 0, 0.16);
}
.wx-line__stripe { position: absolute; left: 0; top: 0; bottom: 0; width: 6px; background: #C1C7D0; }
.wx-line--pending      .wx-line__stripe { background: #C1C7D0; }
.wx-line--weighing     .wx-line__stripe { background: linear-gradient(180deg, #2A65B8, #0052CC); }
.wx-line--awaitingcheck .wx-line__stripe { background: linear-gradient(180deg, #FFB048, #F59E0B); }
.wx-line--done         .wx-line__stripe { background: linear-gradient(180deg, #4ADE80, #00875A); }
.wx-line--over         .wx-line__stripe { background: linear-gradient(180deg, #FF7452, #DE350B); }
.wx-line--under        .wx-line__stripe { background: linear-gradient(180deg, #38BDF8, #0EA5E9); }
.wx-line__seq {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; border-radius: 50%;
    background: var(--pw-bg); border: 1.5px solid var(--pw-border);
    font: 800 13px var(--pw-mono); color: var(--pw-text-muted);
}
.wx-line__main { flex: 1; min-width: 0; }
.wx-line__name { font-size: 14px; font-weight: 700; color: var(--pw-primary); line-height: 1.25; }
.wx-line--done .wx-line__name { text-decoration: line-through; color: var(--pw-text-muted); }
.wx-line__meta { font-size: 11px; color: var(--pw-text-muted); margin-top: 2px; }
.wx-line__right { flex-shrink: 0; text-align: right; }
.wx-line__target { font: 800 16px var(--pw-mono); color: var(--pw-primary); }
.wx-line__actual { font-size: 11px; margin-top: 1px; }

/* --- Banner mất kết nối cân --- */
.wx-disc {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 14px;
    background: #FFEBE6; border: 1px solid #FFBDAD; border-left: 4px solid #DE350B;
    border-radius: 8px;
    font: 700 12px var(--pw-sans); color: #BF2600;
    flex-shrink: 0;
}

/* --- Responsive: dưới 960px xếp dọc (panel trên, queue dưới) --- */
@media (max-width: 960px) {
    .wx { height: auto; min-height: calc(100dvh - 56px); overflow: visible; }
    .wx-stage { grid-template-columns: 1fr; }
    .wx-panel { height: auto; min-height: 60vh; }
    .wx-queue { height: auto; max-height: 70vh; }
    .wx-lcd__value { font-size: 68px; }
}
@media (max-width: 600px) {
    .wx-lcd__value { font-size: 54px; }
    .wx-lcd__uom { font-size: 22px; }
    .wx-mat__batch { margin-left: 0; }
    .wx-bigbtn { min-height: 68px; font-size: 14px; }
}


/* ==========================================================================
   CreateOrderDialog redesign (P2 industrial-precise) — BOM readout + preset chips
   ========================================================================== */
/* ── CreateOrderDialog: preset segmented row (chip toggles cho kích thước mẻ) ── */
.pw-preset-row {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 4px;
}
.pw-preset-row__label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--pw-text-muted);
    margin-right: 2px;
}

/* ── CreateOrderDialog: BOM readout panel (một trong hai "màn hình hiển thị" có viền) ── */
.pw-bom-panel {
    border: 1px solid var(--pw-border);
    border-radius: 6px;
    overflow: hidden;
    background: var(--pw-surface);
}
.pw-bom-panel__head {
    padding: 8px 12px;
    background: #FAFBFC;
    border-bottom: 1px solid var(--pw-border);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--pw-text-muted);
}
.pw-bom-panel__sub {
    text-transform: none;
    letter-spacing: normal;
    font-weight: 500;
    color: var(--pw-text-muted);
}
/* #4 Cuộn cả hai trục: header dính; trên webview hẹp bảng cuộn ngang trong giếng, dialog không tràn ngang. */
.pw-bom-scroll {
    max-height: 280px;
    overflow: auto;
}
.pw-bom-table {
    width: 100%;
    min-width: 520px;
    border-collapse: collapse;
    font-size: 12px;
}
.pw-bom-th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: #FAFBFC;
    padding: 6px 12px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--pw-text-muted);
    text-align: left;
    border-bottom: 2px solid var(--pw-border);
    white-space: nowrap;
}
.pw-bom-th--num { text-align: right; }
.pw-bom-tr { border-bottom: 1px solid #EBECF0; }
.pw-bom-tr:nth-child(even) { background: #FCFCFD; }
.pw-bom-tr:hover { background: #F4F8FE; }
.pw-bom-td { padding: 5px 12px; vertical-align: top; }
.pw-bom-td.pw-cell-num { white-space: nowrap; }
.pw-bom-uom {
    font-size: 10px;
    color: var(--pw-text-muted);
}
.pw-bom-tfoot {
    border-top: 2px solid var(--pw-border);
    background: #FAFBFC;
}
.pw-bom-tfoot .pw-bom-td { padding: 7px 12px; }
