/* KPI bar, luoi 14 card PLC, man chi tiet may (machine status / trace / inspection)
   Tach tu Sumida_Traceability_Mock_UI.html — KHONG sua thu tu nap file,
   cascade CSS / thu tu khai bao JS phu thuoc vao no. */
  /* ===== KPI BAR ===== */
  .kpi-bar{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-bottom:10px;flex-shrink:0;background:#fff;border:2px solid #1B1B1B;padding:9px}
  /* ===== TOP PAGE: MỘT khung bao trọn phạm vi + KPI + tab/dải =====
     Viền chỉ nằm ở .ov-frame; mọi khối con bỏ viền ngoài để không thành khung lồng khung,
     ngăn cách nhau bằng đường kẻ mảnh. Phải nối tiếp chuỗi flex (flex column + min-height:0)
     xuống tới #rt-timeline, đứt một cấp là dải không co được và sinh scroll. */
  .ov-frame{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;
    background:#fff;border:2px solid #1B1B1B;padding:9px}
  /* Thanh tiêu đề của khung: margin âm để chạy hết bề ngang, dính sát viền như caption
     của một hộp, không phải một dòng chữ trôi bên trong. */
  .ov-frame-ttl{flex-shrink:0;margin:-9px -9px 9px;padding:6px 10px;background:#1B1B1B;color:#fff;
    font-size:12.5px;font-weight:800;letter-spacing:.6px;text-transform:uppercase}
  .ov-head{flex-shrink:0;background:#fff;padding:0;margin-bottom:9px}
  .ov-head .ctxbar{margin:0 0 9px}
  .ov-head .kpi-bar{border:2px solid #1B1B1B;padding:9px;margin-bottom:0;background:#fff}
  /* Tab kiểu GẠCH CHÂN: nền sáng phẳng, tab đang chọn đánh dấu bằng vạch vàng dưới chân
     thay vì đổ nền xám. Bỏ vạch ngăn dọc giữa các tab — chữ đậm/nhạt đã đủ phân biệt. */
  .ov-frame > .subtabs{border:0;border-bottom:1px solid #C9C9C9;background:transparent}
  .ov-frame > .subtabs .subtab{background:transparent;border-right:0;color:#7a7a7a;box-shadow:none;padding:7px 18px}
  .ov-frame > .subtabs .subtab:hover{background:rgba(0,0,0,.04);color:#333}
  /* Vạch vàng vẽ bằng inset shadow + margin âm 1px để nó đè lên, làm đứt đường kẻ chân
     thanh tab ngay dưới tab đang chọn. */
  .ov-frame > .subtabs .subtab.active{color:#111;box-shadow:inset 0 -3px 0 #B8860B;
    position:relative;margin-bottom:-1px}
  .ov-frame > .subpanel{border:0;padding:11px 0 0}
  /* Cỡ chữ KPI cân theo bảng bên dưới (dòng 32–51px tuỳ màn) — số phải đọc được
     từ vài mét. Màn thấp 1366×768 thu nhỏ lại ở css/05 để không ăn chỗ của bảng. */
  .kpi{background:#fff;border:1px solid #1B1B1B;border-radius:4px;padding:9px 16px;display:flex;flex-direction:column;gap:2px}
  .kpi .lbl{font-size:12.5px;color:#555;text-transform:uppercase;letter-spacing:.5px}
  .kpi .val{font-size:30px;font-weight:800;line-height:1.15}
  .kpi.ok .val{color:#1E8A2E}
  .kpi.ng .val{color:#C9272F}
  .kpi.yld .val{color:#1565C0}

  /* ===== TOP PAGE — BẢNG SẢN LƯỢNG THEO MÁY =====
     Thay lưới card cũ: dự án sau 20–30 máy thì lưới card vỡ bố cục, bảng thì không. */
  /* Viền 1px: bảng đã nằm trong .ov-frame (2px) nên để 2px nữa thành hai khung đen dày
     lồng nhau chỉ cách 11px, nhìn rất nặng. */
  .ov-prod{flex:1;min-height:0;display:flex;flex-direction:column;background:#fff;border:1px solid #1B1B1B}
  .ov-prod .tblwrap{flex:1;min-height:0;overflow:auto;border:none;max-height:none}
  /* Bảng giãn kín chiều cao còn lại — cùng cách xử lý với timeline realtime, để 2 tab
     của Top Page cao bằng nhau. `height:100%` khiến các dòng chia đều phần dư. */
  .ov-prod table.tbl{height:100%}
  .ov-prod table.tbl th{font-size:13px;padding:9px 6px}
  .ov-prod table.tbl td{font-size:14px}
  .ov-prod table.tbl td.l{font-size:14.5px}
  .ov-prod table.tbl td .mono{font-size:12.5px}
  .ov-prod table.tbl tbody tr{cursor:pointer}
  .ov-prod table.tbl tbody tr:hover td{background:#E8F0FE}
  .ov-prod tr.ov-alarm td{background:#FFEAEA}
  .ov-prod tr.ov-oven td{background:#F4F1FB;color:#555}
  .ov-prod .v-in{color:#1565C0;font-weight:700}
  .ov-prod .v-zero{color:#9A9A9A;font-weight:800}
  .ov-prod .ov-dim{color:#888}
  /* Nút nổi 💡 Đề xuất (fixed, right:24px bottom:42px) được phép nổi ĐÈ lên góc dưới-phải
     của khung — đó là chỗ trống. Chỉ chừa lề phải cho dòng chữ ở đáy khung để không có
     chữ nào chui xuống dưới nút. Trước đây chừa hẳn 52px đáy trang, để lại một dải xám
     trống to giữa khung và thanh trạng thái. */
  #page-overview{padding-bottom:14px}
  #page-overview .note,#page-overview .ov-foot{padding-right:150px}
  .ov-foot{font-size:11.5px;color:#555;padding:5px 9px;border-top:1px solid #ddd;background:#FAFAFA;flex-shrink:0}
  /* Trạng thái = CHỮ trần, không khung. Nền dòng đã tô hồng khi máy lỗi nên thêm
     khung nữa là thừa; bảng 14 dòng mà mỗi dòng một khung màu thì rất nhiễu. */
  .ov-st{font-size:13px;font-weight:700;white-space:nowrap}
  .ov-st.run{color:#146C2E}
  .ov-st.alarm{color:#C9272F;font-weight:800}
  .ov-st.off{color:#777}
  /* Thanh tỷ lệ đạt — WPF map sang ProgressBar, không cần thư viện biểu đồ */
  .ov-ratecell{display:flex;align-items:center;gap:6px}
  .ov-bar{flex:1;min-width:48px;height:15px;background:#E6E6E6;border:1px solid #C4C4C4;overflow:hidden}
  .ov-bar>i{display:block;height:100%;background:#2ECC40}
  .ov-bar.mid>i{background:#F2C014}
  .ov-bar.low>i{background:#E63946}
  .ov-pct{font-weight:800;font-size:13.5px}
  .ov-pct.hi{color:#1E8A2E}.ov-pct.mid{color:#B07A00}.ov-pct.low{color:#C9272F}
  .ov-sw{display:inline-block;width:11px;height:11px;border:1px solid #888;vertical-align:-1px}
  .ov-sw.hi{background:#2ECC40}.ov-sw.mid{background:#F2C014}.ov-sw.low{background:#E63946}
  @keyframes blink{0%,100%{opacity:1}50%{opacity:.3}}   /* dùng ở đèn báo lỗi màn Chi tiết máy */

  /* ===== PLC DETAIL ===== */
  .insp-section{margin-top:14px;background:#fff;border:1px solid #111}
  .insp-section h3{margin:0;padding:5px 8px;background:#1F1F1F;color:#fff;font-size:13px;text-align:center;letter-spacing:.5px}
  .insp-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:0;border-top:1px solid #ddd}
  .insp-cell{padding:8px 10px;border-right:1px solid #eee;border-bottom:1px solid #eee}
  .insp-cell .lbl{font-size:11px;color:#666;text-transform:uppercase;letter-spacing:.4px}
  .insp-cell .val{font-size:18px;font-weight:800;color:#111}
  .insp-cell .unit{font-size:11px;color:#666;margin-left:3px;font-weight:400}
  .insp-cell.ng{background:#FFEAEA}
  .insp-cell.ng .val{color:#C9272F}
  .insp-cell.ok{background:#EAFBEA}
  .insp-cell.ok .val{color:#1E8A2E}
  /* Trạng thái máy = 3 CHIP trên thanh đầu màn (trước là 1 dải tiêu đề + 3 ô cao ~120px
     chỉ để chứa 3 chữ). Chip mang đủ đèn + nhãn + dòng phụ, cao 26px. */
  .ms-chips{display:flex;gap:7px;flex-wrap:wrap}
  .ms-chip{display:inline-flex;align-items:center;gap:6px;background:#F1FAF2;border:1px solid #9ED6A8;
    border-radius:13px;padding:3px 11px;font-size:12.5px;font-weight:700;color:#146C2E;white-space:nowrap}
  .ms-chip>i{width:9px;height:9px;border-radius:50%;background:#2ECC40;flex-shrink:0}
  .ms-chip>em{font-style:normal;font-weight:400;font-size:11px;color:#6a8a70}
  .ms-chip.bad{background:#FFEAEA;border-color:#E08A8A;color:#A5121B}
  .ms-chip.bad>i{background:#E63946;animation:blink 1s infinite}
  .ms-chip.bad>em{color:#a97}
  .ms-chip.stop{background:#EFEFEF;border-color:#BDBDBD;color:#555}
  .ms-chip.stop>i{background:#888}
  .ms-chip.stop>em{color:#888}

  /* Bảng bộ đếm: gộp "Đang chạy" + "Lần chạy trước" thành 2 cột giá trị */
  /* Bó bề ngang: 3 cột trải hết 1340px thì số nằm rời rạc, mắt phải quét ngang xa */
  .cnt-table{width:100%;max-width:820px;border-collapse:collapse;font-size:13px}
  .cnt-table th{background:#EDEDED;padding:5px 12px;font-size:12px;border-bottom:1px solid #ccc;text-align:right}
  .cnt-table th.k{text-align:left}
  .cnt-table th.prev,.cnt-table td.prev{color:#777;background:#FAFAFA}
  .cnt-table td{padding:4px 12px;border-bottom:1px solid #eee;text-align:right}
  .cnt-table td.k{text-align:left;color:#444}
  .cnt-table td.num{font-weight:800;font-size:16px}
  .cnt-table tr:last-child td{border-bottom:none}

  /* Traceability code cards (MaterialLot / Carrier2D / WindingChuck2D / Base2D) */
  .trace-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:0;border-top:1px solid #ddd}
  .trace-cell{padding:10px 12px;border-right:1px solid #eee;display:flex;flex-direction:column;gap:4px}
  .trace-cell .lbl{font-size:11px;color:#666;text-transform:uppercase;letter-spacing:.4px}
  .trace-cell .val{font-size:14px;font-weight:700;color:#111;font-family:Consolas,"SF Mono",monospace;word-break:break-all}
  .trace-cell.key{background:#FFF8DC;border-left:3px solid #B8860B}
  .trace-cell.key .lbl{color:#B8860B}
  .trace-cell .scan{font-size:10px;color:#888;margin-top:2px}
  .trend-box{margin-top:14px;background:#fff;border:1px solid #111;padding:10px}
  .trend-box h3{margin:0 0 8px;font-size:13px;text-align:center;background:#1F1F1F;color:#fff;padding:6px;letter-spacing:.5px}
  .trend-canvas{height:160px;width:100%}

  /* ===== MÀN CHI TIẾT MÁY — ô trường dữ liệu theo 4 trạng thái nguồn =====
     Mục đích: phân biệt rõ "có data thật" / "export rỗng" / "có tag nhưng export
     chưa có" / "doc 09/07 yêu cầu mà chưa có tag". Trước đây mọi ô đều là số minh
     hoạ nên không nói được điều gì về thứ đang thật sự thu được. */
  .insp-grid .trace-cell,.insp-grid .insp-cell{border-right:1px solid #eee;border-bottom:1px solid #eee;
    padding:6px 10px;display:flex;flex-direction:column;gap:2px;min-width:0}
  .trace-cell.st-data,.insp-cell.st-data{background:#F4FBF4}
  .trace-cell.st-empty,.insp-cell.st-empty{background:#FFF6F6}
  .trace-cell.st-iomap,.insp-cell.st-iomap{background:#F7F7F7}
  .trace-cell.st-need,.insp-cell.st-need{background:#FFF8E1;border-left:3px solid #B8860B}
  .trace-cell.key,.insp-cell.key{box-shadow:inset 3px 0 0 #1E88E5}
  .insp-grid .trace-cell .lbl,.insp-grid .insp-cell .lbl{font-size:11px;color:#555;text-transform:none;
    letter-spacing:0;line-height:1.3;display:flex;gap:5px;align-items:baseline;flex-wrap:wrap}
  .insp-grid .trace-cell .val,.insp-grid .insp-cell .val{font-size:15px;font-weight:800;color:#111;
    font-family:Consolas,"SF Mono",monospace;word-break:break-all;line-height:1.25}
  .f-dim{color:#aaa !important;font-weight:600 !important}
  .f-state{font-size:10.5px;color:#8a7a4a}
  .f-dev{font-size:10.5px;color:#1565C0}
  .f-tag{font-size:10px;color:#888;font-family:Consolas,monospace;word-break:break-all}
  .f-tag-none{color:#B8860B;font-style:italic}
  .f-note{font-size:10.5px;color:#7a5800;background:#FFFDF5;border-left:2px solid #E0C878;
    padding:3px 6px;margin-top:2px;line-height:1.4}
  .f-mat .qrow{display:flex;justify-content:space-between;gap:6px;font-size:10.5px;line-height:1.4;
    border-bottom:1px dotted #cfcfcf;padding:1px 0}
  .f-mat .qrow:last-child{border-bottom:none}
  .f-mat .qrow span:first-child{color:#666;white-space:nowrap}
  .f-mat .qrow span:last-child{font-family:Consolas,monospace;font-weight:700;color:#111;
    overflow:hidden;text-overflow:ellipsis}

  /* Băng nguồn số liệu + chú giải 4 trạng thái */
  /* Thanh đầu màn gộp 3 việc: chip trạng thái máy · nguồn số liệu · chú giải 4 màu ô */
  .f-legend{background:#fff;border:1px solid #111;padding:6px 10px;margin-bottom:10px;font-size:12px;
    display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;align-items:center}
  .f-src{color:#444;flex:1;min-width:220px}
  .f-legend-keys{display:flex;gap:13px;flex-wrap:wrap;font-size:11px;color:#555}
  .f-legend-keys span{display:inline-flex;align-items:center;gap:5px}
  .f-legend-keys .sw{width:13px;height:13px;border:1px solid #999;display:inline-block;flex-shrink:0}
  .f-legend-keys .sw.st-data{background:#F4FBF4}
  .f-legend-keys .sw.st-empty{background:#FFF6F6}
  .f-legend-keys .sw.st-iomap{background:#F7F7F7}
  .f-legend-keys .sw.st-need{background:#FFF8E1;border-color:#B8860B}

  /* Trường export chưa có định nghĩa — hiện nguyên mã gốc */
  .f-rawwrap{display:flex;flex-wrap:wrap;gap:6px}
  .f-raw{font-family:Consolas,monospace;font-size:11px;background:#F0F0F0;border:1px solid #ccc;
    border-radius:3px;padding:2px 7px;color:#333}
  .f-raw b{color:#1565C0}
