
  :root{
    --nav-h: 65px;
    --deep: #067884;
    --sand: #eef7f6;
    --card: #FFFFFF;
    --ink: #0b2530;
    --muted: #5b7b82;
    --rust: #d9600a;
    --rust-dim: #fbe0d5;
    --good: #1a8a5c;
    --warn: #C1962F;
    --bad: #B84A3A;
    --line: #d7e4e2;
    --mono: "SF Mono", "Consolas", "Menlo", monospace;
    --disp: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    --body: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  }
  *{box-sizing:border-box;}
  body{ margin:0; font-family:var(--body); background:var(--sand); color:var(--ink); display:flex; flex-direction:column; min-height:100vh; }
  nav{ width:100%; flex-shrink:0; background:linear-gradient(135deg,#1c3d54,#2a5674); color:var(--sand); position:sticky; top:0; z-index:100; }
  nav .topbar-row{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding:10px 20px; border-bottom:1px solid rgba(255,255,255,0.12); flex-wrap:wrap; }
  nav .brand{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-right:auto; }
  nav .nav-menu-wrap{ position:relative; flex-shrink:0; }
  nav #sidebar-toggle-btn{ background:rgba(255,255,255,0.08); color:#E4E9E7; border:1px solid rgba(255,255,255,0.18); border-radius:4px; padding:7px 11px; font-size:16px; font-family:var(--body); cursor:pointer; white-space:nowrap; flex-shrink:0; }
  nav #sidebar-toggle-btn:hover{ background:rgba(255,255,255,0.16); }
  nav .brand h1{ font-family:var(--disp); font-weight:700; font-size:17px; margin:0; line-height:1; letter-spacing:0.01em; white-space:nowrap; }
  /* Sapaan user, rata kanan di header. .brand punya margin-right:auto, itu yang
     mendorong blok ini ke ujung kanan topbar. Tombol Keluar SENGAJA tidak di
     sini melainkan di sidebar: .topbar-row memakai flex-wrap, jadi di layar HP
     isi header yang terlalu lebar terdorong ke baris kedua — header jadi dua
     baris, dan karena tingginya dipakai memosisikan sidebar (--nav-h), tab
     paling atas jadi tertutup. */
  nav .topbar-actions{ display:flex; align-items:center; gap:12px; margin-left:auto; min-width:0; }
  nav .nav-user-greeting{ font-size:13px; font-weight:600; color:#E4E9E7; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
  nav .topbar-actions button{ background:rgba(255,255,255,0.08); color:#E4E9E7; border:1px solid rgba(255,255,255,0.18); border-radius:4px; padding:7px 12px; font-size:12px; font-family:var(--body); cursor:pointer; white-space:nowrap; }
  nav .topbar-actions button:hover{ background:rgba(255,255,255,0.16); }
  /* Tombol Muat Ulang Data — bundar, di ujung kanan bar (sesudah sapaan),
     supaya beda bentuk dari tombol kotak lain di bar ini (☰, dst) walau
     warnanya tetap satu keluarga. Berputar terus selama fetchInitialData()
     berjalan (class "muat" dari window.__refreshDftData di app2.js), bukan
     cuma animasi sesaat, supaya benar-benar menunjukkan sedang memuat. */
  nav .topbar-actions .nav-refresh-btn{ background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.18); border-radius:50%; width:34px; height:34px; padding:0; display:inline-flex; align-items:center; justify-content:center; color:#E4E9E7; cursor:pointer; flex-shrink:0; }
  nav .topbar-actions .nav-refresh-btn:hover{ background:rgba(255,255,255,0.16); }
  nav .topbar-actions .nav-refresh-btn svg{ display:block; }
  nav .topbar-actions .nav-refresh-btn.muat svg{ animation:nav-refresh-spin .8s linear infinite; }
  @keyframes nav-refresh-spin{ from{ transform:rotate(0deg); } to{ transform:rotate(360deg); } }
  @media (prefers-reduced-motion: reduce){
    nav .topbar-actions .nav-refresh-btn.muat svg{ animation:none; opacity:.5; }
  }
  /* Tombol Keluar di dasar sidebar, tepat di bawah tab Pengaturan. */
  .sheet-tabs .sidebar-logout{ display:flex; align-items:center; justify-content:flex-start; gap:8px; width:100%; box-sizing:border-box; margin-top:10px; padding:11px 14px; background:none; border:none; border-top:1px solid rgba(255,255,255,0.14); color:#F0B4A2; font-family:var(--body); font-size:13px; font-weight:600; text-align:left; white-space:nowrap; overflow:hidden; cursor:pointer; border-radius:4px; }
  .sheet-tabs .sidebar-logout:hover{ background:rgba(232,115,74,0.18); color:#fff; }
  .sheet-tabs.collapsed .sidebar-logout{ justify-content:center; padding:11px 0; }
  .sheet-tabs.collapsed .sidebar-logout .label{ display:none; }
  .app-shell{ display:flex; align-items:flex-start; flex:1; min-height:0; }
  .sheet-tabs{ display:flex; flex-direction:column; background:linear-gradient(180deg,#2a5674,#1c3d54); padding:8px 12px; flex:0 0 220px; width:220px; box-sizing:border-box; position:sticky; top:var(--nav-h, 0px); align-self:flex-start; max-height:calc(100vh - var(--nav-h, 0px)); overflow-y:auto; transition:width .18s ease, flex-basis .18s ease, padding .18s ease; }
  .sheet-tabs.collapsed{ flex:0 0 52px; width:52px; padding:8px 6px; }
  .sheet-tabs button.tab{ display:flex; align-items:center; justify-content:flex-start; gap:8px; width:100%; box-sizing:border-box; text-align:left; background:none; border:none; color:#CBDAD6; font-family:var(--body); font-size:13px; padding:11px 14px; cursor:pointer; border-left:3px solid transparent; border-radius:4px; }
  /* text-overflow:ellipsis di elemen flex CONTAINER (di atas) tidak pernah
     benar-benar terpotong dengan titik-titik — itu cuma bekerja pada
     elemen yang teksnya langsung meluber, bukan pada flex child seperti
     .label di sini. Dulu ini membuat label terpotong mentah di tengah kata
     ("Update Harga dan Kalkulatc") tanpa "..." sama sekali. Aturannya
     dipindah ke .label sendiri, dengan min-width:0 supaya flex child boleh
     menyusut lebih kecil dari lebar teksnya (bawaan flex adalah TIDAK
     boleh, itu sebabnya ellipsis-nya tidak pernah aktif). */
  .sheet-tabs button.tab .label{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .sheet-tabs.collapsed button.tab{ justify-content:center; padding:11px 0; }
  .sheet-tabs.collapsed button.tab .label{ display:none; }
  /* Penanda di kiri tiap tab. Isinya CAMPURAN: sebagian besar nomor urut
     (01–10) sebagai teks mono kecil, dua di antaranya ikon (Dashboard dan
     Obrolan). Lebarnya dipatok 20px untuk KEDUANYA supaya semua label mulai
     di garis yang sama — nomor mono dan emoji lebarnya berbeda, dan tanpa
     patokan ini tepi kiri teksnya terlihat bergerigi. */
  .sheet-tabs button.tab .n{
    font-family:var(--mono); font-size:10.5px; color:#6F9A92;
    width:20px; flex:none; text-align:center; display:inline-block;
  }
  /* Ikon perlu jauh lebih besar dari nomor: pada 10,5px emoji nyaris tak
     terbaca. Font & warna dikembalikan ke bawaan karena keduanya tidak
     berlaku untuk emoji berwarna. */
  .sheet-tabs button.tab .n.ikon{
    font-family:inherit; font-size:15px; line-height:1;
  }
  .sheet-tabs button.tab:hover{ background:rgba(255,255,255,0.06); color:#fff; }
  .sheet-tabs button.tab.active{ background:var(--sand); color:var(--deep); border-left:3px solid var(--rust); font-weight:700; border-radius:0 6px 6px 0; }
  .sheet-tabs button.tab.active .n{ color:var(--rust); }
  main{ flex:1; min-width:0; padding:32px 48px 60px; max-width:1600px; width:100%; margin:0 auto; }
  .panel{ display:none; }
  .panel.active{ display:block; animation:fade .18s ease; }
  @keyframes fade{ from{opacity:0; transform:translateY(4px);} to{opacity:1; transform:translateY(0);} }
  /* Sub-tab horizontal — dipakai di tab Referensi (Multi FR / Update Harga)
     dan BOP (Biaya Operasional / Gudang).
     Bentuknya "kelompok tombol tersegmen", bukan garis bawah tipis seperti
     sebelumnya. Garis bawah 2px nyaris tidak terbaca sebagai pilihan di layar
     HP — pengguna tidak sadar ada isi lain di baliknya, dan tab kedua praktis
     tidak pernah dibuka. Latar berkotak membuatnya langsung terbaca sebagai
     "pilih salah satu", dan yang aktif ditandai blok warna penuh, bukan
     sekadar beda warna huruf. */
  .ref-subtabs{
    display:flex; gap:4px; flex-wrap:wrap;
    margin:16px 0 20px; padding:4px;
    background:var(--sand);
    border:1px solid var(--line);
    border-radius:10px;
    /* fit-content supaya tidak melar selebar layar di desktop — kelompok
       tombol yang terlalu lebar justru kehilangan kesan "satu kesatuan". */
    width:fit-content; max-width:100%;
  }
  .ref-subtab{
    appearance:none; border:none; cursor:pointer; background:transparent;
    padding:9px 18px; border-radius:7px;
    font-family:var(--body); font-size:13.5px; font-weight:600;
    color:var(--muted); white-space:nowrap;
    transition:background .15s ease, color .15s ease, box-shadow .15s ease;
  }
  .ref-subtab:hover:not(.active){ background:rgba(255,255,255,.75); color:var(--ink); }
  .ref-subtab.active{
    background:var(--deep); color:#fff;
    box-shadow:0 1px 3px rgba(6,120,132,.35);
  }
  @media (max-width:720px){
    /* Di HP dibuat selebar layar dan dibagi rata — jadi target ketuknya besar
       dan tidak ada tombol yang terlihat "terselip" di pinggir. */
    .ref-subtabs{ width:100%; }
    .ref-subtab{ flex:1 1 auto; text-align:center; padding:10px 12px; font-size:13px; }
  }
  /* Tombol pilihan grafik Dashboard: judulnya besar semua, dan label yang
     panjang (mis. "Estimasi Pendapatan/Keuntungan") boleh membungkus 2 baris
     di layar sempit -- beda dari .ref-subtab lain yang labelnya pendek dan
     sengaja nowrap. */
  .db-grafik-tombol .ref-subtab{
    text-transform:uppercase;
    white-space:normal;
    text-align:center;
    line-height:1.25;
  }

  /* Dropdown kustom -- awalnya utk pemilih Kolam/Menampilkan di Performa
     Kolam, sekarang dipakai ULANG utk SEMUA <select> di aplikasi lewat
     kustomkanSelect()/kustomkanSemuaSelect() (app2.js). <select> BAWAAN
     dibuang: di Android/iOS daftarnya dirender penuh layar oleh OS sendiri,
     gaya kotaknya tidak bisa disentuh sama sekali dari CSS -- jadi apa pun
     yang dipasang di sini di desktop tetap tampil sebagai pemilih OS polos
     begitu dibuka di HP. Ini pengganti tampilan sepenuhnya (tombol + daftar
     biasa), supaya tampilannya SAMA di desktop maupun HP. */
  /* flex:1 1 auto di sini murni jaga-jaga: beberapa baris di app ini
     menata input+select berdampingan lewat "select{flex:1}" pada elemen
     <select> aslinya (mis. .ka-scope .meta, .wqm-scope .filter-row) --
     karena select aslinya sekarang disembunyikan di dalam .dd-custom,
     .dd-custom sendiri yang perlu ikut melebar mengisi baris flex itu.
     Tidak berpengaruh sama sekali di luar konteks flex (grid/blok biasa).
     margin-bottom:12px menyamai punya "input, select" bawaan -- <select>
     ASLI kini disembunyikan (tidak lagi ikut alur normal dokumen), jadi
     jarak bawahnya yg dulu otomatis ada HARUS dipindah ke .dd-custom
     sendiri, kalau tidak elemen sesudahnya (deskripsi/label field lain)
     jadi menempel/bertumpuk dgn tombol dropdown ini (dilaporkan di BOP,
     Referensi, Rekap Panen, Penjualan). */
  .dd-custom{ position:relative; flex:1 1 auto; min-width:0; margin-bottom:12px; }
  /* <select> ASLI dibungkus .dd-custom, TETAP ADA di DOM (bukan
     display:none) supaya kode lama yang baca/tulis .value atau dengar
     'change' tetap jalan apa adanya -- cuma disembunyikan dari layar. */
  select.dd-custom-native{
    position:absolute; opacity:0; width:1px; height:1px; margin:0; padding:0;
    border:0; pointer-events:none; overflow:hidden;
  }
  /* Label pemilihan boleh panjang (nama Farm, atau label siklus spt
     "Siklus Terbaru/Berjalan") -- dipotong "..." dalam SATU baris, bukan
     dibiarkan membungkus 2 baris (bikin tombolnya jadi tinggi sebelah &
     ikonnya melayang aneh, terutama di HP yang lebarnya sempit). */
  .dd-custom-label, .dd-custom-btn span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
  .dd-custom-btn{
    width:100%; display:flex; align-items:center; justify-content:space-between; gap:8px;
    font-family:var(--mono); font-size:13px; font-weight:600; color:var(--ink); background:#FBF9F3;
    border:1px solid var(--line); border-radius:4px; padding:9px 10px;
    cursor:pointer; text-align:left; appearance:none; touch-action:manipulation;
  }
  .dd-custom-btn:hover{ border-color:var(--deep); }
  .dd-custom-btn[aria-expanded="true"]{ border-color:var(--deep); box-shadow:0 0 0 2px rgba(6,120,132,.15); }
  .dd-custom-btn[disabled]{ opacity:0.65; cursor:default; }
  .dd-custom-caret{ color:var(--muted); flex:none; transition:transform .12s ease; }
  .dd-custom-btn[aria-expanded="true"] .dd-custom-caret{ transform:rotate(180deg); }
  .dd-custom-list{
    position:absolute; top:calc(100% + 4px); left:0; right:0; z-index:30;
    background:var(--card); border:1px solid var(--line); border-radius:6px;
    box-shadow:0 8px 24px rgba(11,37,48,.16); max-height:260px; overflow-y:auto; padding:4px;
    overscroll-behavior:contain;
  }
  /* touch-action:manipulation -- browser mobile langsung memproses tap
     sebagai tap (bukan menunggu ~300ms utk mastiin bukan double-tap-zoom,
     jeda yg bikin gesture scroll & tap jadi ambigu di daftar sependek
     ini). Mengurangi risiko jari yang sedikit bergeser saat tap kena
     ke-anggap scroll lalu "melayang" ke baris tetangga. */
  .dd-custom-opt{
    padding:9px 10px; border-radius:4px; font-family:var(--mono); font-size:13px; font-weight:600;
    color:var(--ink); cursor:pointer; white-space:nowrap; touch-action:manipulation;
  }
  .dd-custom-opt.disabled{ color:var(--muted); cursor:default; opacity:0.6; }
  .dd-custom-opt:hover:not(.disabled){ background:var(--sand); }
  .dd-custom-opt.active{ background:var(--deep); color:#fff; }
  /* Target sentuh lebih longgar di HP -- daftar OS yang digantikan ini
     biasanya bertuts besar juga. */
  @media (max-width:720px){
    .dd-custom-opt{ padding:12px 10px; font-size:13.5px; }
  }

  /* Baris Filter Farm/Blok + Filter Siklus di Dashboard. max-width di sini
     cuma relevan di layar lebar (dua kotak berdampingan, tidak melar penuh
     tanpa batas) -- di HP dilepas total & masing-masing kotak jadi
     selebar baris sendiri, supaya labelnya (mis. "Siklus Terbaru/
     Berjalan") tidak dipaksa muat di kotak sempit 220px lalu membungkus. */
  .db-filter-row{ display:flex; gap:16px; flex-wrap:wrap; margin-bottom:12px; }
  .db-filter-col{ max-width:240px; flex:1 1 200px; min-width:160px; }
  @media (max-width:720px){
    .db-filter-row{ gap:10px; }
    .db-filter-col{ max-width:none; flex:1 1 100%; min-width:0; }
  }

  header.page{ margin-bottom:22px; }
  header.page h2{ font-family:var(--disp); font-size:28px; margin:4px 0 6px; font-weight:700; }
  header.page p{ margin:0; color:var(--muted); font-size:12.5px; max-width:640px; line-height:1.5; }
  .grid{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }

  /* Grid rapat untuk isian pendek — angka, size, harga.
     auto-fit + minmax berarti jumlah kolomnya MENYESUAIKAN lebar yang ada:
     empat di layar lebar, dua di tablet, satu di HP. Tidak perlu media query
     terpisah, dan tidak pernah memaksa isian berdesakan sampai tak terbaca.
     min-width:0 wajib — bawaan grid item adalah min-width:auto, sehingga isi
     yang lebih lebar dari kolomnya meluber keluar kartu alih-alih menyusut. */
  .grid-rapat{ display:grid; grid-template-columns:repeat(auto-fit, minmax(160px, 1fr)); gap:12px; }
  .grid-rapat > *{ min-width:0; }
  @media (max-width:720px){ .grid{ grid-template-columns:1fr; } main{ padding:20px 16px 50px; width:100%; } nav .topbar-row{ padding:8px 12px; flex-wrap:nowrap; } nav .brand h1{ font-size:15px; } nav .topbar-actions button{ padding:6px 9px; font-size:11px; } nav #sidebar-toggle-btn{ padding:6px 9px; font-size:14px; }
    /* Sapaan "Halo, nama" / "KODE PERUSAHAAN" ditampilkan lagi di HP
       (window.__syncNavUser sudah memanggil __syncNavHeight() setiap kali
       teksnya berubah, jadi --nav-h selalu ikut disegarkan — lihat app2.js).
       Supaya topbar-row TIDAK ikut melebar ke baris kedua, greeting-nya
       sendiri yang jadi 2 baris — dan baris keduanya (nav-user-line2) DIPAKSA
       ke baris tersendiri (bukan sekadar wrap bebas), supaya potongannya
       selalu tepat di antara nama & kode perusahaan, bukan di tengah kode
       itu sendiri (mis. "PT-" kepotong dari "PIB"). */
    nav .nav-user-greeting{
      display:block; white-space:normal; overflow:visible; text-overflow:clip;
      font-size:11px; line-height:1.35; max-width:130px; text-align:right;
    }
    nav .nav-user-line1, nav .nav-user-line2{ display:block; }
    .app-shell{ position:relative; }
    .sheet-tabs{ position:fixed; left:0; top:var(--nav-h, 0px); bottom:0; z-index:90; width:240px; flex:0 0 auto; max-height:none; box-shadow:2px 0 14px rgba(0,0,0,.3); transition:transform .2s ease; transform:translateX(0); }
    .sheet-tabs.collapsed{ transform:translateX(-100%); width:240px; padding:8px 12px; }
    .sheet-tabs.collapsed button.tab{ justify-content:flex-start; padding:11px 14px; }
    .sheet-tabs.collapsed button.tab .label{ display:inline; }
    /* Di HP sidebar tidak menyempit melainkan menggeser keluar layar, jadi saat
       "collapsed" labelnya tetap harus utuh — sama seperti tab di atasnya. */
    .sheet-tabs.collapsed .sidebar-logout{ justify-content:flex-start; padding:11px 14px; }
    .sheet-tabs.collapsed .sidebar-logout .label{ display:inline; }
    .sidebar-backdrop{ display:none; position:fixed; inset:0; top:var(--nav-h,0px); background:rgba(0,0,0,.35); z-index:80; }
    .sidebar-backdrop.show{ display:block; }
  }
  @media (min-width:721px) and (max-width:1100px){ .sheet-tabs{ flex:0 0 190px; width:190px; } .sheet-tabs button.tab{ font-size:12px; padding:10px 10px; } }
  .card{ background:var(--card); border:1px solid var(--line); border-radius:6px; padding:18px 20px; margin-bottom:16px; }
  /* Kartu ringkas per siklus tebar — menggantikan tabel 13 kolom yang sulit
     dibaca sekilas, terutama di layar HP. Tabel penuhnya tetap ada di bawah. */
  #stocking-cards{ display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:12px; }
  .st-card{ border:1px solid var(--line); border-left:4px solid var(--good); border-radius:6px; padding:12px 14px; background:#fff; }
  .st-card.selesai{ border-left-color:var(--muted); opacity:.82; }
  .st-card .sc-head{ display:flex; justify-content:space-between; align-items:baseline; gap:8px; margin-bottom:2px; }
  .st-card .sc-kolam{ font-family:var(--disp); font-weight:700; font-size:15px; color:var(--deep); }
  .st-card .sc-sub{ font-size:11.5px; color:var(--muted); margin-bottom:10px; }
  .st-card .sc-stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; padding:9px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
  .st-card .sc-stat .lbl{ font-size:10px; text-transform:uppercase; letter-spacing:.03em; color:var(--muted); }
  .st-card .sc-stat .val{ font-family:var(--disp); font-weight:700; font-size:16px; color:var(--ink); line-height:1.2; }
  .st-card .sc-stat .unit{ font-size:10px; color:var(--muted); font-weight:400; }
  .st-card .sc-foot{ margin-top:9px; font-size:11.5px; color:var(--muted); line-height:1.6; }
  @media (max-width:720px){ #stocking-cards{ grid-template-columns:1fr; } }
  .card h3{ font-family:var(--disp); font-size:15px; text-transform:uppercase; letter-spacing:0.04em; margin:0 0 14px; color:var(--deep); border-bottom:1px solid var(--line); padding-bottom:8px; display:flex; justify-content:space-between; align-items:baseline; }
  .card h3 .tag{ font-family:var(--mono); font-size:10px; color:var(--muted); text-transform:none; letter-spacing:0; font-weight:400; }
  .card p.desc{ font-size:13px; color:var(--muted); margin:-4px 0 14px; }
  label{ display:block; font-size:12.5px; color:var(--muted); margin-bottom:4px; font-weight:600; }
  input, select{ width:100%; padding:9px 10px; font-family:var(--mono); font-size:13px; font-weight:600; border:1px solid var(--line); border-radius:4px; background:#FBF9F3; color:var(--ink); margin-bottom:12px; }
  input:disabled{ opacity:0.65; }
  input:focus, select:focus{ outline:2px solid var(--rust); outline-offset:1px; border-color:var(--rust); }
  .hint{ font-size:11.5px; color:var(--muted); margin-top:-8px; margin-bottom:12px; }

  /* Peringatan "kolam sudah Panen Akhir" di panel input harian (Feeding,
     Rekap Sampling, WQ, Kontrol Anco, Blind Feeding) -- SEKADAR peringatan,
     bukan penghalang: form tetap berfungsi normal, cuma diberi tanda supaya
     tidak diisi tanpa sadar siklusnya sudah ditutup. display:none default,
     dimunculkan lewat JS (renderPeringatanSiklusSelesai). */
  .peringatan-siklus-selesai{
    display:none;
    margin:8px 0 14px;
    padding:10px 12px;
    background:var(--rust-dim, #fbe0d5);
    border:1px solid var(--rust);
    border-radius:8px;
    font-size:12.5px;
    color:var(--rust);
    font-weight:600;
    line-height:1.4;
  }

  /* Judul kartu untuk panel biasa.
     Selama ini `.card-title` HANYA didefinisikan di dalam .ka-scope dan
     .wqm-scope, sehingga kartu di panel lain yang memakainya tampil sebagai
     paragraf polos — dan `.hint` yang margin-atasnya -8px menariknya naik
     sampai menimpa judulnya. Disamakan dengan `.card h3` supaya konsisten. */
  .card-title{
    display:flex; align-items:center; justify-content:space-between; gap:10px;
    font-family:var(--disp); font-size:15px; text-transform:uppercase;
    letter-spacing:0.04em; font-weight:700; color:var(--deep);
    margin:0 0 14px; border-bottom:1px solid var(--line); padding-bottom:8px;
    flex-wrap:wrap;
  }
  .card-title .left{ display:flex; align-items:center; gap:8px; }
  .card-title .dot{ width:7px; height:7px; border-radius:50%; background:var(--rust); flex:none; }
  .card-title .tag{ font-family:var(--mono); font-size:10px; color:var(--muted);
    text-transform:none; letter-spacing:0; font-weight:400; }
  /* Netralkan margin negatif `.hint` saat ia menempel langsung di bawah judul —
     margin itu memang dirancang untuk menempel di bawah ISIAN, bukan judul. */
  .card-title + .hint{ margin-top:0; }
  .readout{ display:flex; flex-wrap:wrap; gap:12px; margin-top:4px; }
  .stat{ flex:1; min-width:140px; background:var(--deep); color:#FFFFFF; border-radius:6px; padding:14px 16px; }
  .stat .label{ font-size:11px; text-transform:uppercase; letter-spacing:0.06em; color:#C8E4DE; font-weight:600; }
  .stat .value{ font-family:var(--mono); font-size:24px; font-weight:700; margin-top:4px; color:#FFFFFF; overflow-wrap:break-word; word-break:break-word; }
  .stat .unit{ font-family:var(--mono); font-size:12px; color:#C8E4DE; margin-left:4px; }
  .stat.rust{ background:var(--rust); }
  .stat.rust .label{ color:#FFEFE4; }
  .stat.rust .unit{ color:#FFEFE4; }
  .gauge{ margin-top:10px; }
  .gauge .track{ height:8px; background:var(--line); border-radius:4px; overflow:hidden; }
  .gauge .fill{ height:100%; border-radius:4px; transition:width .25s ease; }
  .gauge .row{ display:flex; justify-content:space-between; font-size:11px; color:var(--muted); margin-top:4px; font-family:var(--mono); }
  table{ width:100%; border-collapse:collapse; font-size:13px; }
  table th, table td{ text-align:left; padding:7px 8px; border-bottom:1px solid var(--line); }
  table th{ font-family:var(--mono); font-size:11px; text-transform:uppercase; color:var(--muted); letter-spacing:0.03em; white-space:nowrap; }
  table td.num{ font-family:var(--mono); white-space:nowrap; }
  /* Tabel label-nilai (tab Extra: Perencanaan/Akad/Hasil Bagi) -- satu baris
     satu field, meniru cara ngisi sel di Excel (label sempit kiri, nilai
     lebar kanan) alih-alih kotak label-di-atas-input seperti form lain. */
  table.kv-table td:first-child{ width:260px; font-weight:600; color:var(--deep); }
  table.kv-table td input, table.kv-table td select{ margin-bottom:0; }
  /* Tabel Rincian per Kolam (Extra > Perencanaan Budidaya) -- header 2 baris
     (nama lalu satuan, mis. "Target Size" / "ekor/kg") supaya nama field yang
     panjang tidak memaksa kolomnya ikut lebar. Lebar tiap kolom input diatur
     mengikuti BANYAKNYA DIGIT isiannya, bukan ikut lebar 100% bawaan --
     Target SR/FCR/Size cuma 2-5 digit, Harga Benur/Pakan/Jual bisa 6 digit. */
  table.pr-rincian-table th{ white-space:nowrap; }
  table.pr-rincian-table tr.pr-subhead th{ font-weight:400; font-size:10px; opacity:.75; padding-top:0; }
  table.pr-rincian-table .pr-row-sr,
  table.pr-rincian-table .pr-row-fcr,
  table.pr-rincian-table .pr-row-size{ width:58px; }
  table.pr-rincian-table .pr-row-benur-netto,
  table.pr-rincian-table .pr-row-benur-aktual{ width:92px; }
  table.pr-rincian-table .pr-row-harga-benur,
  table.pr-rincian-table .pr-row-harga-pakan,
  table.pr-rincian-table .pr-row-harga-jual{ width:98px; }
  tr.current{ background:var(--rust-dim); }
  /* Garis vertikal antar kolom -- dipakai tabel dengan banyak kolom angka
     berdempetan (mis. Program Pakan Harian), supaya batas tiap kolom jelas
     tanpa perlu menghitung spasi. Kolom terakhir tidak diberi garis kanan
     supaya tidak menempel ke tepi area scroll. */
  .tbl-garis-kolom th, .tbl-garis-kolom td{ border-right:1px solid var(--line); }
  .tbl-garis-kolom th:last-child, .tbl-garis-kolom td:last-child{ border-right:none; }
  .table-scroll{ overflow-x:auto; }

  /* Kontrol Anco — Pengaturan Tahap DOC (rentang DOC/anco%/target menit
     yang bebas diatur tenan sendiri, menggantikan tabel tahap baku lama). */
  .ka-stage-cfg{ border-top:1px dashed var(--line); padding-top:12px; }
  .ka-stage-row{ display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-bottom:8px; padding:8px; background:var(--panel-2,rgba(0,0,0,0.03)); border-radius:8px; }
  .ka-stage-row .ka-sr-field{ display:flex; flex-direction:column; gap:2px; }
  .ka-stage-row label{ font-size:10px; text-transform:uppercase; letter-spacing:0.03em; color:var(--muted); }
  .ka-stage-row select, .ka-stage-row input{ font-size:13px; padding:5px 6px; border:1px solid var(--line); border-radius:6px; background:var(--bg,#fff); color:var(--ink); width:78px; }
  .ka-stage-row .ka-sr-del:hover{ background:var(--bad); color:#fff; }
  .ka-stage-row .ka-sr-save:hover{ opacity:.9; }

  /* Riwayat Blind Feeding: 8 kolom terlalu banyak untuk layar HP kalau
     dipaksa menyempit ke lebar layar — judulnya pecah jadi 2-3 baris acak
     ("DIS/IMP/AN") dan kolom terakhir malah ikut terpotong di tepi. Di HP,
     biarkan tabelnya SELEBAR ISINYA (tidak dipaksa 100%) dan geser ke
     samping lewat .table-scroll — setiap judul kolom jadi satu baris utuh,
     lebih enak dibaca daripada dipaksa muat. Desktop tidak disentuh sama
     sekali (cukup lebar, tidak perlu ini). */
  @media (max-width:720px){
    .bf-hist-scroll table{ width:auto; min-width:640px; }
    .bf-hist-scroll th, .bf-hist-scroll td{ white-space:nowrap; }
  }

  /* Tabel Rekap Sampling: 19 kolom — terlalu banyak untuk dipaksa muat
     bahkan di desktop, judulnya tetap terasa sesak/susah dibaca walau
     tidak separah di HP. Berlaku SELALU (tidak dibatasi @media seperti
     Riwayat Blind Feeding) — lebar alami + scroll ke samping di semua
     ukuran layar, bukan dipaksa menyempit. */
  .rk-hist-scroll table{ width:auto; min-width:1400px; }
  .rk-hist-scroll td{ white-space:nowrap; border-right:1px solid var(--line); }
  .rk-hist-scroll th{ white-space:normal; word-break:normal; overflow-wrap:normal; vertical-align:top; border-right:1px solid var(--line); }
  .rk-hist-scroll th:last-child, .rk-hist-scroll td:last-child{ border-right:none; }

  /* Tabel Data Stocking: 13 kolom — perlakuan sama seperti Rekap Sampling
     di atas (lebar alami + scroll + garis kolom), alasannya sama persis. */
  .st-hist-scroll table{ width:auto; min-width:1000px; }
  .st-hist-scroll td{ white-space:nowrap; border-right:1px solid var(--line); }
  .st-hist-scroll th{ white-space:normal; word-break:normal; overflow-wrap:normal; vertical-align:top; border-right:1px solid var(--line); }
  .st-hist-scroll th:last-child, .st-hist-scroll td:last-child{ border-right:none; }

  /* Tabel rekap lain dengan pola masalah yang sama (banyak kolom, dipaksa
     menyempit) — perlakuan identik: lebar alami + scroll + garis kolom +
     judul boleh 2 baris di batas kata (bukan potong huruf). Dikelompokkan
     dalam satu aturan supaya tidak diulang-ulang per tabel. */
  .bf-prog-scroll table, .rm-hist-scroll table, .pn-hist-scroll table, .bop-hist-scroll table, .fd-hist-scroll table{
    width:auto; min-width:900px;
  }
  .bf-prog-scroll td, .rm-hist-scroll td, .pn-hist-scroll td, .bop-hist-scroll td, .fd-hist-scroll td{
    white-space:nowrap; border-right:1px solid var(--line);
  }
  .bf-prog-scroll th, .rm-hist-scroll th, .pn-hist-scroll th, .bop-hist-scroll th, .fd-hist-scroll th{
    white-space:normal; word-break:normal; overflow-wrap:normal; vertical-align:top; border-right:1px solid var(--line);
  }
  .bf-prog-scroll th:last-child, .bf-prog-scroll td:last-child,
  .rm-hist-scroll th:last-child, .rm-hist-scroll td:last-child,
  .pn-hist-scroll th:last-child, .pn-hist-scroll td:last-child,
  .bop-hist-scroll th:last-child, .bop-hist-scroll td:last-child,
  .fd-hist-scroll th:last-child, .fd-hist-scroll td:last-child{
    border-right:none;
  }
  /* Log Pakan Harian cuma 6 kolom pendek — min-width kelompok di atas
     (900px) kebesaran untuk tabel sesempit ini, bikin ada jarak kosong
     lebar tidak perlu. Dipersempit khusus di sini. */
  .fd-hist-scroll table{ min-width:0; }
  .note{ font-size:12.5px; color:var(--muted); background:#F0ECE0; border-left:3px solid var(--rust); padding:10px 12px; border-radius:0 4px 4px 0; margin-top:10px; line-height:1.5; }
  .badge{ display:inline-block; font-family:var(--mono); font-size:11px; padding:2px 8px; border-radius:10px; font-weight:700; text-transform:uppercase; }
  .badge.good{ background:#E1EEE3; color:var(--good); }
  .badge.warn{ background:#F5EBD8; color:var(--warn); }
  .badge.bad{ background:#F5E1DC; color:var(--bad); }
  .save-row{ display:flex; gap:10px; align-items:end; flex-wrap:wrap; margin-bottom:14px; }
  .save-row > div{ flex:1; min-width:120px; }
  .save-btn{ background:var(--rust); color:#fff; border:none; border-radius:4px; padding:9px 16px; font-size:13px; font-weight:700; cursor:pointer; height:37px; white-space:nowrap; }
  .save-btn:hover{ background:#A9542A; }
  .del-btn{ background:none; border:1px solid var(--line); color:var(--bad); border-radius:4px; padding:4px 9px; font-size:11px; cursor:pointer; font-family:var(--body); }
  .del-btn:hover{ background:#F5E1DC; }
  .empty-hist{ font-size:12.5px; color:var(--muted); font-style:italic; padding:6px 0; }
  table input[type="number"], table input[type="text"]{ margin-bottom:0; }

  /* Ringkasan per Kolam (Dashboard): judul kolom dibungkus (bukan
     white-space:nowrap satu tabel penuh), dan baris berselang-seling
     warna teal — senada dengan logo DFT (gradasi teal/turquoise). */
  table.db-ringkasan thead tr{ background:linear-gradient(135deg,#0e4d63,#098089); }
  table.db-ringkasan thead th{ color:#eef7f6; padding:8px 6px; font-size:10px; line-height:1.3; text-wrap:balance; vertical-align:bottom; max-width:90px; }
  table.db-ringkasan tbody td, table.db-ringkasan tfoot td{ font-size:12.5px; padding:6px 6px; }
  table.db-ringkasan tbody tr:nth-child(odd){ background:#eef7f6; }
  table.db-ringkasan tbody tr:nth-child(even){ background:#d7e9e8; }
  table.db-ringkasan tbody tr:hover{ background:#c3ddda; }
  table.db-ringkasan tbody tr.current{ background:var(--rust-dim) !important; }
  table.db-ringkasan tfoot tr{ background:#0e4d63; color:#eef7f6; font-weight:700; }
  table.db-ringkasan tfoot td{ border-bottom:none; }
  table.db-ringkasan tfoot td[style*="--good"]{ color:#7CE0B8 !important; }

  /* Tabel transposed (kolam jadi kolom, metrik jadi baris): kolom label
     metrik dibekukan di kiri supaya tetap terbaca saat digeser ke kanan
     mencari kolam yang jauh — sama seperti kolom pertama spreadsheet.
     border-collapse:collapse (bawaan tabel lain) DIMATIKAN khusus di sini:
     kombinasi position:sticky + border-collapse:collapse punya bug render
     yang dikenal luas — menyisakan celah kecil tepat di sebelah sel yang
     dibekukan. border-spacing:0 membuatnya tetap terlihat rapat seperti
     collapse, tanpa memicu bug itu. table-layout:fixed + width:auto
     (BUKAN width:100% dari aturan global table{}) supaya lebar tiap kolom
     PERSIS mengikuti "width" di baris pertama, dan tabel selebar jumlah
     kolomnya sendiri lalu digulir oleh .table-scroll. */
  table.db-ringkasan-transpose{ border-collapse:separate; border-spacing:0; table-layout:fixed; width:auto; }
  table.db-ringkasan-transpose td.db-metrik-label, table.db-ringkasan-transpose thead th:first-child{
    position:sticky; left:0; z-index:5;
    background:#0e4d63; color:#eef7f6;
    font-family:var(--mono); font-size:11px; text-transform:uppercase; letter-spacing:0.02em;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; box-shadow:2px 0 4px rgba(0,0,0,.15);
    width:132px; max-width:none;
  }
  table.db-ringkasan-transpose tbody td:not(.db-metrik-label){ width:130px; max-width:none; }
  table.db-ringkasan-transpose thead th:not(:first-child){ width:130px; max-width:none; white-space:nowrap; }
  table.db-ringkasan-transpose thead th .badge{ display:block; margin-top:3px; }

  /* Geser di HP berhenti tepat per satu kolam (bukan bebas berhenti di
     tengah), supaya satu kolam selalu terbaca utuh setelah swipe — kolom
     label metrik yang dibekukan di kiri dikecualikan, itu bukan target
     geser, itu memang selalu tampil. overflow-anchor:none mematikan
     "scroll anchoring" bawaan browser — tanpa ini, browser diam-diam
     menahan posisi geser ke kolom yang kebetulan sedang di layar SEBELUM
     tabel dirender ulang, membuat scrollLeft=0 yang di-set lewat JS seolah
     tidak berpengaruh. Snap HANYA aktif di HP (lihat media query di bawah)
     — di desktop dikembalikan polos, tanpa snap dan tanpa reset posisi
     paksa apa pun. */
  .db-scroll-snap{ -webkit-overflow-scrolling:touch; }
  @media (max-width:720px){
    /* mandatory — proximity terbukti geser manual bisa berhenti di
       tengah-tengah (kurang dari lebar 1 kolom), tidak nyandar rapi ke
       kolam manapun. mandatory MEMAKSA selalu berhenti tepat di titik
       snap terdekat. Risiko lama (mandatory "melawan" reset posisi dari
       JS saat render ulang) tidak lagi jadi masalah karena scrollLeft=0
       itu sendiri adalah titik snap yang sah (sesi 1 kolam pertama), jadi
       tidak ada yang "dilawan". */
    /* scroll-padding-left WAJIB ada bersama kolom beku (sticky) — tanpa
       ini, browser menganggap tepi kiri area geser ada di posisi 0, padahal
       132px pertama TERTUTUP kolom RINCIAN yang dibekukan. Akibatnya saat
       menyandar (snap), kolom kolam diletakkan di posisi 0 alias PERSIS DI
       BAWAH kolom RINCIAN — kolamnya "masuk ke dalam" kolom rincian, dan
       yang terlihat cuma sisa badge/teksnya yang menyembul. Dengan
       scroll-padding-left 132px, browser tahu tepi kiri yang benar-benar
       terlihat ada di 132px, jadi kolam disandarkan TEPAT di sebelah kanan
       kolom RINCIAN. */
    /* Nilai 132px di sini cuma cadangan sebelum JS sempat mengukur — angka
       yang dipakai sesungguhnya adalah --db-metrik-w / scrollPaddingLeft
       hasil PENGUKURAN NYATA lebar kolom RINCIAN (lihat app2.js), karena
       lebar render sel tabel = width + padding, selalu lebih besar dari
       angka yang ditulis di CSS. */
    .db-scroll-snap{ scroll-snap-type:x mandatory; overflow-anchor:none; scroll-padding-left:var(--db-metrik-w, 132px); }
  }
  .db-scroll-snap table.db-ringkasan-transpose th:not(:first-child),
  .db-scroll-snap table.db-ringkasan-transpose td:not(.db-metrik-label){
    scroll-snap-align:start;
  }
  /* Di HP, SATU kolam saja per layar (di luar kolom METRIK yang dibekukan)
     — supaya tidak ada sisa/potongan kolam lain yang ikut terlihat dan
     membingungkan. Lebar kolom METRIK KONSTAN 132px, jadi tinggal
     dikurangkan langsung di sini; SISA lebar wadah tabel itu semua jadi
     milik satu kolom kolam. */
  @media (max-width:720px){
    .db-scroll-snap table.db-ringkasan-transpose th:not(:first-child),
    .db-scroll-snap table.db-ringkasan-transpose td:not(.db-metrik-label){
      /* TANPA pengurangan ekstra: lebar kolam = sisa lebar wadah setelah
         dikurangi kolom RINCIAN, pas tanpa sisa. Dulu dikurangi lagi 6-14px
         sebagai "ruang aman", tapi justru selisih itulah yang bikin kolam
         berikutnya mengintip di tepi layar (diuji: -6px → mengintip 6,4px;
         tanpa pengurangan → 0,4px alias tak terlihat). --db-metrik-w sudah
         hasil ukur nyata (lihat app2.js), jadi tidak perlu ruang aman lagi. */
      min-width:calc(var(--db-scroll-w, 100vw) - var(--db-metrik-w, 132px));
      width:calc(var(--db-scroll-w, 100vw) - var(--db-metrik-w, 132px));
    }
  }

  /* Kartu ringkasan di Dashboard: mengikuti gradasi logo DFT (hijau ke
     teal/turquoise), bukan navy+oranye tema umum aplikasi. */
  #p-dashboard .stat{ background:linear-gradient(135deg,#0e4d63,#098089); }
  #p-dashboard .stat.rust{ background:linear-gradient(135deg,#2f9e6f,#098089); }
  #p-dashboard .save-btn{ background:linear-gradient(135deg,#0e4d63,#098089); }
  #p-dashboard .save-btn:hover{ background:#098089; }

  /* ===== Resume Budidaya (sub-tab Dashboard) =====
     Struktur tabel (label beku di kiri, kolam sbg kolom) diambil dari format
     laporan investor yang dicontohkan user, tapi WARNANYA tetap tema DFT --
     gradasi teal/hijau logo yang sama dgn kartu ringkasan & header tabel
     .db-ringkasan yang sudah ada, bukan palet baru. */
  .rb-titlebar{
    background:linear-gradient(135deg,#0e4d63,#098089); color:#fff;
    font-family:var(--disp); font-weight:700; font-size:13.5px;
    text-transform:uppercase; letter-spacing:0.04em;
    padding:10px 14px; margin:-1px -1px 14px;
  }
  .resume-budidaya{ padding:0 0 14px; overflow:hidden; }
  .resume-budidaya .table-scroll{ padding:0 14px 14px; }
  /* thead/label beku/selang-seling baris TIDAK di-override -- sudah benar
     dari .db-ringkasan/.db-ringkasan-transpose (gradasi teal yang sama). */
  /* Baris ditonjolkan (mis. Survival Rate) -- tint hijau DFT (var(--good)),
     bukan warna baru, supaya tetap terbaca sbg "metrik baik" konsisten
     dgn badge Untung/SELESAI yang sudah ada di app. */
  .resume-budidaya table.rb-table tr.rb-row-sorot td:not(.db-metrik-label){ background:#c7ead9 !important; font-weight:700; color:var(--deep); }
  /* Angka finansial utama (Modal Awal, Laba Bersih) -- tint rust DFT
     (var(--rust-dim)), sama seperti baris "sedang disunting" yang sudah
     dipakai di tabel lain -- bukan warna baru. */
  .resume-budidaya table.rb-table tr.rb-row-keuangan-utama td:not(.db-metrik-label){ background:var(--rust-dim, #fbe0d5) !important; color:var(--rust); font-weight:700; }
  .resume-budidaya table.rb-table td.rb-col-average{ font-weight:700; }
  /* Kolom RINCIAN DIPATOK 208px di KEDUA tabel Resume.
     Kenapa perlu: aturan umum .db-ringkasan-transpose menulis width:132px,
     tapi angka itu TIDAK PERNAH berlaku di sini. Sel label memakai
     white-space:nowrap, dan pada table-layout:fixed dengan width:auto isi
     yang tidak boleh turun baris selalu menang atas width yang ditulis —
     jadi lebar kolom sesungguhnya ditentukan oleh LABEL TERPANJANG di
     masing-masing tabel. Hasilnya dua tabel yang bertumpuk punya lebar
     kolom pertama BERBEDA (terukur 175px di Budidaya vs 206,3px di
     Keuangan), sehingga seluruh kolom kolam meleset 31,3px satu sama lain.
     208px dipilih karena label terpanjang di kedua tabel ("Laba Bersih
     Syirkah yang Dibagi") butuh 207px termasuk padding — dipatok TEPAT DI
     ATAS kebutuhan itu supaya isinya tidak lagi bisa mendorong kolom
     melebar, tanpa ada satu label pun yang terpotong. */
  .resume-budidaya table.rb-table td.db-metrik-label,
  .resume-budidaya table.rb-table thead th:first-child{ width:208px; min-width:208px; }
  /* Baris total selebar tabel (mis. % Nett Profit/Modal) -- satu sel
     colspan penuh, bukan per kolam. */
  .resume-budidaya table.rb-table tr.rb-row-total-lebar td{ background:linear-gradient(135deg,#0e4d63,#098089) !important; color:#fff; font-weight:700; text-align:center; }

  /* ===== Tab 07: Update Harga dan Kalkulator (embedded module, scoped under .ph-scope) ===== */

  
  .ph-scope{
    --deep:#067884;
    --sea:#0e4d63;
    --teal:#098089;
    --foam:#eef7f6;
    --sand:#f7f3ea;
    --coral:#d9600a;
    --ink:#0b2530;
    --line:#d7e4e2;
    --good:#1a8a5c;
  
    margin:0;
    background:var(--foam);
    color:var(--ink);
    font-family:'Segoe UI', system-ui, -apple-system, sans-serif;
  }

  .ph-scope label{ display:inline; font-size:inherit; color:inherit; margin-bottom:0; font-weight:inherit; }
  .ph-scope input, .ph-scope select{ width:auto; padding:0; font-family:inherit; font-size:inherit; border:none; border-radius:0; background:transparent; color:inherit; margin-bottom:0; }

  .ph-topbar{
    background:linear-gradient(135deg,var(--deep),var(--sea));
    color:var(--foam);
    padding:22px 18px 60px;
    position:relative;
    overflow:hidden;
    border-radius:14px;
  }
  .ph-topbar::after{
    content:"";
    position:absolute;
    right:-40px; bottom:-60px;
    width:220px; height:220px;
    border-radius:50%;
    background:radial-gradient(circle at 30% 30%, rgba(26,138,138,.55), transparent 70%);
  }
  .ph-topbar h1{
    margin:0;
    font-size:1.35rem;
    letter-spacing:.2px;
  }
  .wrap{
    max-width:880px;
    margin:16px auto 20px;
    padding:0 14px;
  }
  /* Panel Update Harga: sama seperti Kontrol Anco dan WQ Monitoring, pembungkus
     ini warisan halaman yang dulunya berdiri sendiri. Di dalam panel DFT,
     880px membuat isinya terkurung dan sisa ruangnya terbuang. */
  .ph-scope .wrap{ max-width:100%; margin:0 0 20px; padding:0; }

  /* Tinggi tabel dipatok 420px, tanpa peduli layarnya. Di layar lebar
     menyisakan ruang kosong di bawahnya; di HP yang pendek justru memakan
     hampir seluruh layar sehingga isian di atasnya ikut terdorong hilang.
     max-height dengan satuan layar (vh) menyesuaikan keduanya. */
  /* SENGAJA tinggi pasti (60vh), bukan auto. Tabel ini memakai gulir virtual:
     jumlah baris yang digambar dihitung dari viewport.clientHeight. Dengan
     height:auto, tinggi wadah ditentukan isinya yang berposisi absolut —
     clientHeight bisa terbaca 0 saat pemuatan awal, dan hanya segelintir baris
     yang tergambar sampai pengguna menggulir. 60vh tetap mengikuti layar,
     tapi selalu punya nilai yang pasti. */
  .ph-scope .viewport{ height:60vh; min-height:260px; max-height:560px; }

  /* Bawaan grid item adalah min-width:auto — isi yang lebih lebar dari
     kolomnya akan meluber keluar kartu, bukan menyusut. */
  .ph-scope .thead-row > *, .ph-scope .data-row > *{ min-width:0; }
  .ph-scope .data-row{ overflow-wrap:anywhere; }
  .ph-card{
    background:#fff;
    border-radius:14px;
    box-shadow:0 10px 30px rgba(6,42,58,.12);
    padding:18px;
    margin-bottom:16px;
    border:1px solid var(--line);
  }
  .ph-card h2{
    font-size:.95rem;
    margin:0 0 12px;
    color:var(--sea);
    display:flex;
    align-items:center;
    gap:8px;
  }
  .ph-card h2 .tag{
    background:var(--teal);
    color:#fff;
    font-size:.65rem;
    padding:2px 8px;
    border-radius:20px;
    font-weight:600;
  }
  .date-row{
    display:flex;
    align-items:center;
    gap:10px;
    flex-wrap:wrap;
    background:var(--foam);
    border:1.5px solid var(--line);
    border-radius:8px;
    padding:8px 12px;
    margin-bottom:14px;
  }
  .date-row label{
    font-size:.75rem;
    font-weight:600;
    color:#5b7b82;
  }
  .date-row input[type=date], .date-row input[type=text]{
    border:1.5px solid var(--line);
    border-radius:7px;
    padding:6px 8px;
    font-family:'SF Mono', Consolas, monospace;
    font-size:.82rem;
    background:#fff;
    color:var(--ink);
  }
  .date-row .last-update{
    margin-left:auto;
    font-size:.72rem;
    color:var(--teal);
    font-weight:600;
  }
  .anchor-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(130px,1fr));
    gap:10px;
  }
  .anchor-item label{
    display:block;
    font-size:.72rem;
    color:#5b7b82;
    margin-bottom:4px;
    font-weight:600;
  }
  .anchor-item .row{
    display:flex;
    align-items:center;
    border:1.5px solid var(--line);
    border-radius:8px;
    overflow:hidden;
    background:var(--foam);
  }
  .anchor-item .row span{
    padding:8px 6px;
    font-size:.75rem;
    color:#4a6a70;
    background:#e2eeec;
    border-right:1px solid var(--line);
  }
  .anchor-item input{
    border:none;
    background:transparent;
    padding:8px 6px;
    width:100%;
    font-size:.85rem;
    font-family:'SF Mono', Consolas, monospace;
    color:var(--ink);
  }
  .anchor-item input:focus{outline:2px solid var(--teal); outline-offset:-2px;}
  .anchor-item.readonly .row{background:#e9eeed; cursor:default;}
  .anchor-item.readonly .value{
    padding:8px 6px;
    width:100%;
    font-size:.85rem;
    font-family:'SF Mono', Consolas, monospace;
    color:#7d9a9f;
  }
  .anchor-divider{
    grid-column:1/-1;
    font-size:.7rem;
    color:#7d9a9f;
    font-weight:600;
    margin-top:6px;
    padding-top:10px;
    border-top:1px dashed var(--line);
  }
  .toolbar{
    display:flex;
    flex-wrap:wrap;
    gap:10px;
    align-items:center;
    justify-content:space-between;
  }
  .toolbar .group{display:flex; gap:8px; align-items:center; flex-wrap:wrap;}
  .toolbar label{font-size:.75rem; color:#5b7b82; font-weight:600;}
  .toolbar input[type=number]{
    width:90px;
    padding:7px 8px;
    border:1.5px solid var(--line);
    border-radius:7px;
    font-family:'SF Mono', Consolas, monospace;
  }
  .ph-scope button{
    border:none;
    border-radius:8px;
    padding:8px 14px;
    font-size:.78rem;
    font-weight:600;
    cursor:pointer;
    transition:transform .1s ease;
  }
  .ph-scope button:active{transform:scale(.96);}
  .btn-primary{background:var(--teal); color:#fff;}
  .btn-ghost{background:#e2eeec; color:var(--sea);}
  /* overflow-x:auto, BUKAN overflow:hidden.
     Dulu hidden — dipasang supaya sudut membulatnya rapi — tapi akibatnya
     tabel yang lebih lebar dari layar TERPOTONG tanpa bisa digeser sama
     sekali. Di HP itu berarti kolom paling kanan hilang permanen: di tabel
     Laba/Rugi kolom Margin, dan di Jejak Aktivitas justru kolom berisi
     tombol Pulihkan — fungsinya jadi tidak bisa dipakai, bukan sekadar
     kurang enak dilihat.
     overflow-y tetap hidden supaya pembulatan sudutnya tidak berubah. */
  .table-wrap{
    border:1px solid var(--line);
    border-radius:10px;
    overflow-x:auto;
    overflow-y:hidden;
  }
  .thead-row{
    display:grid;
    grid-template-columns:1fr 1fr;
    background:var(--sea);
    color:#fff;
    font-size:.78rem;
    font-weight:600;
  }
  .thead-row div{padding:10px 12px;}
  .viewport{
    height:420px;
    overflow-y:auto;
    position:relative;
    background:#fff;
  }
  .spacer{position:relative; width:100%;}
  .rows-inner{position:absolute; top:0; left:0; right:0;}
  .data-row{
    display:grid;
    grid-template-columns:1fr 1fr;
    font-size:.82rem;
    font-family:'SF Mono', Consolas, monospace;
    border-bottom:1px solid #eef2f1;
  }
  .data-row:nth-child(even){background:#fbfdfc;}
  .data-row.anchor-row{background:#fff4ec;}
  .data-row div{padding:7px 12px; display:flex; align-items:center;}
  .data-row .price{color:var(--good); font-weight:600;}
  .ph-footer{
    text-align:center;
    font-size:.72rem;
    color:#7d9a9f;
    padding:0 14px 30px;
  }
  .check-table-wrap{
    border:1px solid var(--line);
    border-radius:10px;
    overflow:hidden;
  }
  .check-entry{
    display:flex;
    flex-direction:column;
    gap:8px;
    padding:14px;
    border-bottom:1px solid #eef2f1;
  }
  .check-entry:nth-child(even){background:#fbfdfc;}
  .cf{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:12px;
  }
  .cf-label{
    font-size:.72rem;
    color:#5b7b82;
    font-weight:600;
    min-width:95px;
  }
  .cf input{
    flex:1;
    text-align:right;
    border:1.5px solid var(--line);
    border-radius:6px;
    padding:7px 9px;
    font-family:'SF Mono', Consolas, monospace;
    font-size:.85rem;
  }
  .cf .readonly{
    flex:1;
    text-align:right;
    background:#f2f7f6;
    color:var(--good);
    font-weight:600;
    padding:7px 9px;
    border-radius:6px;
    font-family:'SF Mono', Consolas, monospace;
    font-size:.85rem;
  }
  .check-entry .rm-btn{
    align-self:flex-end;
    background:none;
    border:none;
    color:#c0524a;
    font-size:.78rem;
    font-weight:600;
    cursor:pointer;
    padding:4px 0;
  }
  .check-foot{
    display:flex;
    flex-direction:column;
    gap:6px;
    background:#fff4ec;
    padding:12px 14px;
  }
  .check-foot .cf{font-weight:700; font-size:.85rem; color:var(--sea);}
  .log-actions{display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px;}
  .log-list{border:1px solid var(--line); border-radius:10px; overflow:hidden;}
  .log-entry{padding:14px; border-bottom:1px solid #eef2f1;}
  .log-entry:nth-child(even){background:#fbfdfc;}
  .log-entry-head{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:8px;}
  .log-entry-head .log-date{margin-bottom:0;}
  .log-del-btn{
    background:none; border:none; color:#c0524a;
    font-size:.72rem; font-weight:600; cursor:pointer;
    padding:2px 4px; flex-shrink:0;
  }
  .log-date{font-weight:700; color:var(--sea); font-size:.85rem; margin-bottom:8px;}
  .log-prices{display:grid; grid-template-columns:repeat(auto-fill,minmax(115px,1fr)); gap:6px;}
  .log-price-item{
    display:flex; justify-content:space-between; gap:6px;
    font-size:.76rem; font-family:'SF Mono', Consolas, monospace;
    background:#f7fafa; padding:5px 8px; border-radius:6px;
  }
  .log-price-item.up{color:var(--good); background:#eaf7f1;}
  .log-price-item.down{color:var(--coral); background:#fdf1ec;}
  .log-empty{padding:16px; text-align:center; font-size:.78rem; color:#8aa4a8;}

  /* ===== Splash Screen ===== */
  /* Tampil PERTAMA kali dimuat, di atas segalanya (termasuk kartu login) —
     logo muncul dulu, jargon menyusul sesaat kemudian, lalu memudar begitu
     status login diketahui (lihat JS: sembunyikanSplash()). Ada batas waktu
     tampil MINIMUM (lihat JS) supaya di koneksi cepat pun splash-nya tetap
     terasa ada, bukan cuma berkedip sepersekian detik. */
  #app-splash{
    position:fixed; inset:0; z-index:100000;
    background:linear-gradient(135deg,#1c3d54,#2a5674);
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:14px; text-align:center; padding:24px;
    transition:opacity .35s ease;
  }
  .app-splash-logo{
    width:96px; height:96px; border-radius:22px;
    box-shadow:0 12px 32px rgba(0,0,0,.35);
    animation:splashMuncul .5s ease both;
  }
  .app-splash-nama{
    font-family:var(--disp); font-weight:700; font-size:20px; color:#fff;
    letter-spacing:.01em;
    animation:splashMuncul .5s ease .15s both;
  }
  .app-splash-jargon{
    font-size:13.5px; color:#cfe3e0; line-height:1.5; max-width:280px;
    animation:splashMuncul .5s ease .4s both;
  }
  @keyframes splashMuncul{
    from{ opacity:0; transform:translateY(8px); }
    to{ opacity:1; transform:translateY(0); }
  }

  /* ===== Login Overlay ===== */
  #login-overlay{
    position:fixed; inset:0; z-index:9999; background:linear-gradient(135deg,var(--deep),#041d29);
    /* SENGAJA TANPA align-items:center. Memusatkan lewat align-items pada
       wadah setinggi layar membuat isi yang lebih tinggi dari layar meluber
       ke atas DAN ke bawah, dan bagian atasnya tidak bisa digulir — judul
       serta isian pertama jadi tak terjangkau. Formulir pendaftaran cukup
       panjang, apalagi di HP yang layarnya pendek.
       Pemusatan dilakukan lewat `margin:auto` pada kotaknya: hasilnya sama
       di layar tinggi, tapi tetap bisa digulir saat layar pendek. */
    display:flex; justify-content:center; overflow-y:auto; padding:20px;
    -webkit-overflow-scrolling:touch;
  }
  #login-overlay .login-box{
    background:var(--card); border-radius:10px; padding:32px 30px; width:100%; max-width:360px;
    box-shadow:0 20px 50px rgba(0,0,0,0.35);
    margin:auto;          /* memusatkan tanpa mengorbankan kemampuan menggulir */
    flex:0 0 auto;        /* jangan dipipihkan saat isinya lebih tinggi dari layar */
  }
  #login-overlay .login-eyebrow{ font-family:var(--mono); font-size:10.5px; letter-spacing:0.14em; color:var(--rust); text-transform:uppercase; text-align:center; }
  #login-overlay h1{ font-family:var(--disp); font-size:24px; font-weight:700; margin:6px 0 22px; text-align:center; color:var(--deep); }
  #login-overlay label{ display:block; font-size:12.5px; color:var(--muted); margin-bottom:4px; font-weight:600; }
  #login-overlay input{ width:100%; padding:10px 12px; font-family:var(--body); font-size:14px; border:1px solid var(--line); border-radius:4px; background:#FBF9F3; color:var(--ink); margin-bottom:14px; }
  #login-overlay input:focus{ outline:2px solid var(--rust); outline-offset:1px; border-color:var(--rust); }
  #login-overlay button{ width:100%; background:var(--rust); color:#fff; border:none; border-radius:4px; padding:11px; font-size:14px; font-weight:700; cursor:pointer; margin-top:6px; }
  #login-overlay button:hover{ background:#A9542A; }
  /* Tombol lihat-password: TIDAK ikut aturan #login-overlay button di atas
     (lebar penuh, latar rust) -- ini tombol kecil di dalam kotak isian. */
  .login-pw-wrap{ position:relative; margin-bottom:14px; }
  .login-pw-wrap input{ margin-bottom:0; padding-right:42px; width:100%; }
  #login-overlay .login-pw-toggle{ position:absolute; top:50%; right:4px; transform:translateY(-50%);
    width:auto; margin-top:0; background:none; border:none; color:var(--muted); font-size:16px;
    line-height:1; padding:6px 8px; cursor:pointer; border-radius:4px; }
  #login-overlay .login-pw-toggle:hover{ background:var(--sand); color:var(--deep); }
  #login-overlay .login-pw-toggle.is-visible{ color:var(--rust); }
  #login-overlay .login-error{ font-size:12.5px; color:var(--bad); text-align:center; margin-top:10px; min-height:16px; }

  #login-overlay .login-hint{ font-size:11px; color:var(--muted); text-align:center; margin-top:16px; line-height:1.5; }
  #login-overlay .login-toggle{ font-size:12.5px; color:var(--muted); text-align:center; margin-top:16px; }
  #login-overlay .login-toggle a{ color:var(--rust); font-weight:700; text-decoration:none; cursor:pointer; }
  #login-overlay .login-toggle a:hover{ text-decoration:underline; }
  body.app-locked > nav, body.app-locked > main{ display:none; }

  /* ===== Mode "Lihat Saja" (level akses 3) ===== */
  .panel.sa-view-only::before{
    content: "\1F441\FE0F Mode Lihat Saja — akun Anda tidak bisa menyimpan perubahan di tab ini.";
    display:block; background:#FDE7CE; color:#8A4B12; padding:10px 14px; border-radius:6px;
    font-size:12.5px; font-weight:600; margin-bottom:16px;
  }

  /* ===== Onboarding Wizard (setelah Sign Up) ===== */
  #onboarding-overlay{
    position:fixed; inset:0; z-index:600; background:rgba(11,46,43,0.75);
    display:none; align-items:center; justify-content:center; padding:20px; overflow-y:auto;
  }
  #onboarding-overlay .login-box{
    background:var(--card); border-radius:10px; padding:32px 30px; width:100%;
    box-shadow:0 20px 50px rgba(0,0,0,0.35); max-height:90vh; overflow-y:auto;
  }
  #onboarding-overlay .login-eyebrow{ font-family:var(--mono); font-size:10.5px; letter-spacing:0.14em; color:var(--rust); text-transform:uppercase; text-align:center; }
  #onboarding-overlay h1{ font-family:var(--disp); font-weight:700; margin:6px 0 4px; text-align:center; color:var(--deep); }
  #onboarding-overlay label{ display:block; font-size:12.5px; color:var(--muted); margin-bottom:4px; font-weight:600; }
  #onboarding-overlay input{ width:100%; padding:10px 12px; font-family:var(--body); font-size:14px; border:1px solid var(--line); border-radius:4px; background:#FBF9F3; color:var(--ink); margin-bottom:14px; }
  #onboarding-overlay input:focus{ outline:2px solid var(--rust); outline-offset:1px; border-color:var(--rust); }
  #onboarding-overlay button{ width:100%; background:var(--rust); color:#fff; border:none; border-radius:4px; padding:11px; font-size:14px; font-weight:700; cursor:pointer; margin-top:6px; }
  #onboarding-overlay button:hover{ background:#A9542A; }
  #onboarding-overlay .login-error{ font-size:12.5px; color:var(--bad); text-align:center; margin-top:10px; min-height:16px; }
  #onboarding-overlay .ob-kolam-card{ border:1px solid var(--line); border-radius:8px; padding:14px; margin-bottom:14px; background:#FBF9F3; }
  #onboarding-overlay .ob-kolam-card h4{ margin:0 0 10px; font-size:13px; color:var(--deep); }

  /* ============================================================
     KONTROL ANCO — CSS di-scope penuh ke .ka-scope, ditema ulang
     memakai palet & tipografi DFT yang sama dengan tab lain
     (Program Pakan dkk): --deep, --sand, --card, --rust, --line,
     --disp (Arial Narrow), --body, --mono. Tidak pakai warna/font
     custom (Sora/IBM Plex Mono/dark-teal) lagi.
     ============================================================ */
  .ka-scope{
    display:block;
    color:var(--ink);
    font-family:var(--body);
  }
  .ka-scope *{box-sizing:border-box;}
  /* Dulu max-width:640px — warisan kontrol-anco.html yang aslinya aplikasi
     terpisah selebar layar HP. Di dalam panel DFT yang jauh lebih lebar,
     isinya terkurung di tengah dan sisa ruangnya terbuang. Kartu DFT lain
     sudah mengatur lebar dan paddingnya sendiri, jadi biarkan mengikuti. */
  .ka-scope .wrap{max-width:100%;margin:0;padding:0;}

  .ka-scope .meta{display:flex;gap:10px;margin-bottom:4px;}
  .ka-scope .meta input, .ka-scope .meta select{
    flex:1;background:var(--card);border:1px solid var(--line);
    color:var(--ink);border-radius:6px;padding:10px 12px;font-size:14px;
    font-family:var(--body);
  }
  .ka-scope .meta input::placeholder{color:var(--muted);}

  .ka-scope .card{
    background:var(--card);
    border:1px solid var(--line);
    border-radius:8px;
    padding:18px 16px 20px;
    margin-top:16px;
    position:relative;
  }
  /* overflow:hidden SENGAJA TIDAK dipakai di sini (dulu ada, khusus utk
     memotong bar aksen ::before di bawah supaya rapi mengikuti sudut
     membulat kartu) -- efek sampingnya ikut memotong .dd-custom-list
     (dropdown kustom, lihat dropdownKustomSet/kustomkanSelect di app2.js)
     milik SEMUA <select> di dalam kartu ini, termasuk "Sesi Pakan" pada
     baris Pengaturan Tahap DOC paling bawah -- daftarnya jadi terpotong/
     ketutup kartu berikutnya begitu dibuka, karena harus melebar KELUAR
     kartu tapi kartunya sendiri memotong apa pun yang keluar batasnya.
     Diganti border-radius pada ::before sendiri (menyamai sudut kiri
     kartu) supaya bar aksennya tetap rapi TANPA perlu memotong seluruh isi
     kartu. */
  .ka-scope .card::before{
    content:'';position:absolute;top:0;left:0;width:4px;height:100%;
    background:var(--session-color,var(--rust));
    border-radius:8px 0 0 8px;
  }
  .ka-scope .card-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:14px;}
  .ka-scope .card-title{font-family:var(--disp);font-weight:700;font-size:17px;color:var(--deep);letter-spacing:0.01em;}
  .ka-scope .card-tag{
    font-family:var(--mono);font-size:10.5px;color:var(--muted);
    letter-spacing:.06em;text-transform:uppercase;
  }

  .ka-scope label.field-label{
    display:block;font-size:12.5px;color:var(--muted);margin:0 0 6px;font-weight:600;
  }
  .ka-scope .input-row{margin-bottom:14px;}
  .ka-scope .num-input{
    width:100%;background:var(--sand);border:1px solid var(--line);
    color:var(--ink);border-radius:6px;padding:11px 12px;font-size:16px;
    font-family:var(--mono);font-weight:600;
  }
  .ka-scope .num-input:focus{outline:none;border-color:var(--rust);}

  .ka-scope .checkpoint{
    background:var(--sand);border:1px solid var(--line);border-radius:8px;
    padding:12px 12px 14px;margin-bottom:10px;
  }
  .ka-scope .cp-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;}
  .ka-scope .cp-name{font-size:13px;font-weight:700;color:var(--deep);}
  .ka-scope .cp-toggle{
    display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--muted);
    cursor:pointer;user-select:none;
  }
  .ka-scope .cp-toggle input{accent-color:var(--rust);width:14px;height:14px;}

  .ka-scope .checkpoint.locked{opacity:.6;border-style:dashed;}

  .ka-scope .xyz-row{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap;}
  .ka-scope .score-chip{
    flex:1;min-width:56px;text-align:center;background:var(--card);border:1.5px solid var(--line);
    color:var(--muted);border-radius:6px;padding:11px 4px;font-size:15px;
    font-family:var(--mono);font-weight:600;cursor:pointer;transition:all .12s;
  }
  .ka-scope .score-chip.active{
    background:var(--session-color,var(--rust));border-color:var(--session-color,var(--rust));
    color:#fff;
  }

  .ka-scope .num-input:disabled{opacity:.5;cursor:not-allowed;}

  .ka-scope .sum-note{font-size:10.5px;text-align:center;margin-top:7px;font-family:var(--mono);}
  .ka-scope .sum-ok{color:var(--good);}
  .ka-scope .sum-bad{color:var(--bad);}

  .ka-scope button.calc{
    width:100%;padding:13px;border:none;border-radius:6px;
    background:var(--session-color,var(--rust));color:#fff;
    font-family:var(--disp);font-weight:700;font-size:15px;
    cursor:pointer;margin-top:6px;letter-spacing:.01em;
  }
  .ka-scope button.calc:disabled{opacity:.4;cursor:not-allowed;}
  .ka-scope button.calc:active:not(:disabled){transform:scale(.985);}

  .ka-scope .result{
    margin-top:14px;padding:13px 14px;background:var(--sand);
    border:1px solid var(--session-color,var(--deep));border-radius:8px;
    display:none;
  }
  .ka-scope .result.show{display:block;}
  .ka-scope .result-value{
    font-family:var(--mono);font-size:24px;font-weight:700;
    color:var(--session-color,var(--deep));
  }
  .ka-scope .result-unit{font-size:13px;color:var(--muted);margin-left:4px;}
  .ka-scope .result-trace{
    display:none;
    margin-top:8px;font-size:11.5px;color:var(--muted);line-height:1.6;
    border-top:1px dashed var(--line);padding-top:8px;
  }
  .ka-scope .result-trace b{color:var(--ink);font-weight:700;}

  .ka-scope .summary{margin-top:16px;}
  /* auto-fit, bukan dipatok 2 kolom: di HP jadi satu kolom, di layar lebar
     bisa tiga atau empat. min-width:0 wajib — bawaan grid item adalah
     min-width:auto, sehingga isi yang lebih lebar dari kolomnya meluber
     keluar kartu alih-alih menyusut. */
  .ka-scope .sum-grid{
    display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
    gap:10px; margin-bottom:14px;
  }
  .ka-scope .sum-grid > *{min-width:0;}
  /* Baris isian atas ikut melipat di layar sempit, tidak memaksa berdesakan. */
  .ka-scope .meta{flex-wrap:wrap;}
  .ka-scope .meta input, .ka-scope .meta select{min-width:150px;}
  .ka-scope .sum-item{
    background:var(--sand);border:1px solid var(--line);border-radius:8px;
    padding:12px;
  }
  .ka-scope .sum-item .lbl{font-size:11px;color:var(--muted);margin-bottom:4px;}
  .ka-scope .sum-item .val{font-family:var(--mono);font-size:18px;font-weight:700;color:var(--ink);}
  .ka-scope .sum-total{
    grid-column:1/-1;background:var(--rust-dim);border:1px solid var(--rust);
  }
  .ka-scope .sum-total .val{color:var(--rust);font-size:21px;}

  .ka-scope button.save{
    width:100%;padding:13px;border:2px solid var(--rust);border-radius:6px;
    background:transparent;color:var(--rust);font-family:var(--disp);
    font-weight:700;font-size:15px;cursor:pointer;
  }
  .ka-scope button.save:disabled{opacity:.35;cursor:not-allowed;border-color:var(--line);color:var(--muted);}

  .ka-scope .hist-item{
    display:flex;justify-content:space-between;align-items:center;
    background:var(--sand);border:1px solid var(--line);border-radius:6px;
    padding:10px 12px;margin-bottom:8px;font-size:13px;
  }
  .ka-scope .hist-item .h-main{font-weight:700;color:var(--ink);}
  .ka-scope .hist-item .h-sub{color:var(--muted);font-size:11.5px;font-family:var(--mono);margin-top:2px;}
  .ka-scope .hist-del{background:none;border:none;color:var(--bad);font-size:18px;cursor:pointer;padding:4px 8px;}
  .ka-scope .empty-hist{color:var(--muted);font-size:12.5px;text-align:center;padding:14px 0;}

  .ka-scope footer{
    text-align:center;margin-top:28px;color:var(--muted);
    font-family:var(--mono);font-size:11px;letter-spacing:.05em;
  }

  /* ============================================================
     WQ MONITORING — CSS di-scope ke .wqm-scope, ditema ulang
     memakai palet & tipografi DFT (--deep, --rust, --sand, --line,
     --ink, --muted, --good, --bad, --card, --mono, --body). Struktur
     komponen stepper/chip picker dipertahankan apa adanya (cepat
     diisi tanpa keyboard di HP) — cuma warnanya diganti.
     ============================================================ */
  .wqm-scope{ display:block; color:var(--ink); font-family:var(--body); }
  .wqm-scope *{box-sizing:border-box;}
  /* Tombol tetap huruf biasa. Isian dan dropdown mengikuti seluruh DFT:
     monospace 14px, supaya angka sejajar antar baris dan mudah dibandingkan
     sekilas. Sebelumnya WQM memakai huruf biasa 13px — warisan wqm-dft.html
     yang berdiri sendiri, dan itulah yang membuat tab ini terasa berbeda
     dari yang lain. */
  .wqm-scope button, .wqm-scope textarea{
    font-family:var(--body); font-size:13px; color:var(--ink);
  }
  /* Hanya isian ANGKA yang monospace. Isian teks, tanggal, dropdown, dan
     textarea dikembalikan ke huruf biasa oleh aturan .wqm-scope input[type=date],…
     lebih ke bawah — monospace membuat kalimat panjang lebih sulit dibaca,
     bukan lebih mudah. */
  .wqm-scope input, .wqm-scope select{
    font-family:var(--mono); font-size:14px; color:var(--ink);
  }
  .wqm-scope button{ letter-spacing:0; }
  /* Sama seperti .ka-scope: warisan wqm-dft.html yang aslinya berdiri sendiri
     selebar HP. Di dalam panel DFT, ruangnya terbuang percuma. */
  .wqm-scope .wrap{max-width:100%;margin:0;}

  .wqm-scope .subtabs{display:flex;gap:8px;margin-bottom:14px;}
  /* Diperkecil (9px 6px/12.5px -> 7px 6px/11.5px) supaya sepadat tombol di
     tab lain -- sebelumnya tab ini masih mewarisi ukuran wqm-dft.html yang
     didesain berdiri sendiri selebar HP. */
  .wqm-scope .subtab-btn{flex:1;text-align:center;padding:7px 6px;border-radius:8px;
    background:var(--card);border:1px solid var(--line);color:var(--muted);
    font-size:11.5px;font-weight:700;cursor:pointer;font-family:var(--body);}
  .wqm-scope .subtab-btn.active{background:var(--deep);color:#fff;border-color:var(--deep);}

  .wqm-scope .view{display:none;} .wqm-scope .view.active{display:block;}

  .wqm-scope .card{background:var(--card);border-radius:10px;border:1px solid var(--line);
    padding:16px 14px 18px;margin-bottom:14px;box-shadow:0 1px 2px rgba(6,42,58,.04);}
  /* Disamakan dengan judul kartu DFT (.card h3): 15px, jarak huruf 0.04em,
     tebal 700, bergaris bawah. Sebelumnya 11px dengan jarak huruf 0.08em dan
     tebal 800 — kombinasi kecil, renggang, dan sangat tebal itulah yang membuat
     tab ini terbaca padat dan berbeda sendiri dari tab lain. */
  .wqm-scope .card-title{display:flex;align-items:center;justify-content:space-between;
    font-size:15px;text-transform:uppercase;letter-spacing:.04em;font-weight:700;
    color:var(--deep);margin:0 0 14px;font-family:var(--disp);
    border-bottom:1px solid var(--line);padding-bottom:8px;}
  .wqm-scope .card-title .left{display:flex;align-items:center;gap:8px;}
  .wqm-scope .card-title .dot{width:7px;height:7px;border-radius:50%;background:var(--rust);flex:none;}

  .wqm-scope .pick-grid{display:flex;flex-wrap:wrap;gap:8px;}
  .wqm-scope .pick-chip{border:2px solid var(--line);background:var(--sand);color:var(--ink);
    /* Diperkecil (10px 13px/13px/700 -> 8px 12px/12px/600) menyamai kepadatan
       tombol di tab lain. */
    padding:8px 12px;border-radius:9px;font-size:12px;font-weight:600;
    cursor:pointer;min-width:46px;text-align:center;font-family:var(--body);}
  .wqm-scope .pick-chip.active{background:var(--deep);border-color:var(--deep);color:#fff;}
  .wqm-scope .pick-chip.empty{opacity:.45;cursor:default;}

  .wqm-scope .chip-group{display:flex;flex-wrap:wrap;gap:8px;}
  .wqm-scope .chip{border:1.5px solid var(--line);background:var(--sand);color:var(--muted);
    padding:6px 10px;border-radius:16px;font-size:11.5px;font-weight:600;cursor:pointer;font-family:var(--body);}
  .wqm-scope .chip.active{background:var(--rust);border-color:var(--rust);color:#fff;}
  .wqm-scope .chip.s-active{background:var(--deep);border-color:var(--deep);color:#fff;}

  .wqm-scope .stepper-wrap{display:flex;align-items:center;gap:6px;margin-bottom:6px;}
  .wqm-scope .ps-tag{width:21px;height:21px;border-radius:5px;background:var(--rust);color:#fff;
    font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center;flex:none;}
  .wqm-scope .ps-tag.s{background:var(--deep);}
  .wqm-scope .stepper{display:flex;align-items:center;gap:4px;min-width:0;flex-wrap:wrap;}
  .wqm-scope .sbtn{width:32px;height:32px;border-radius:8px;border:1.5px solid var(--line);
    background:#fff;font-size:14px;font-weight:800;color:var(--deep);cursor:pointer;
    display:flex;align-items:center;justify-content:center;font-family:var(--body);}
  .wqm-scope .sbtn.fine{width:25px;height:25px;font-size:10px;color:var(--muted);}
  .wqm-scope .sbtn:active{background:var(--rust-dim);}
  .wqm-scope .sval{min-width:56px;text-align:center;font-family:var(--mono);font-size:14px;
    font-weight:800;background:var(--rust-dim);border-radius:7px;padding:8px 4px;}
  .wqm-scope .sunit{font-size:10px;color:var(--muted);}

  .wqm-scope .field{margin-bottom:14px;} .wqm-scope .field:last-child{margin-bottom:0;}
  /* Disamakan dengan label di tab lain: abu-abu, tebal 600 — bukan biru tua
     tebal 700. Label yang lebih menonjol daripada isinya menarik perhatian ke
     nama kolom, padahal yang perlu dibaca justru angkanya. */
  .wqm-scope label{display:block;font-size:12.5px;font-weight:600;color:var(--muted);margin-bottom:7px;}
  .wqm-scope .unit{font-weight:400;color:var(--muted);font-size:11px;}
  .wqm-scope .subnote{font-size:11.5px;color:var(--muted);margin-top:6px;}
  .wqm-scope .ghost-btn{background:none;border:none;color:var(--rust);font-size:12px;font-weight:700;cursor:pointer;padding:0;}
  .wqm-scope input[type=date],.wqm-scope select,.wqm-scope textarea,.wqm-scope input[type=text]{
    width:100%;padding:10px;border-radius:8px;border:1.5px solid var(--line);
    font-size:14px;background:var(--sand);font-family:var(--body);outline:none;color:var(--ink);}
  .wqm-scope input[type=date]:focus,.wqm-scope select:focus,.wqm-scope textarea:focus{
    border-color:var(--rust);box-shadow:0 0 0 3px var(--rust-dim);}
  .wqm-scope textarea{resize:vertical;min-height:52px;}

  .wqm-scope .badge-doc{display:inline-flex;align-items:center;gap:6px;background:var(--rust-dim);color:var(--deep);
    padding:6px 12px;border-radius:18px;font-size:12.5px;font-weight:700;margin-top:6px;}
  .wqm-scope .autofill-note{font-size:11.5px;color:var(--good);background:#eaf6f0;padding:7px 10px;
    border-radius:8px;margin-top:8px;}
  .wqm-scope .review-note{font-size:11.5px;font-weight:700;background:#fff3cd;border:1.5px solid #f5c842;
    color:#7a5c00;padding:8px 12px;border-radius:9px;margin-top:8px;}
  .wqm-scope .warn-note{font-size:11.5px;color:var(--bad);margin-top:6px;}

  .wqm-scope .kultur-item{display:flex;align-items:center;gap:10px;margin-bottom:8px;}

  .wqm-scope .mortal-detail{display:none;margin-top:10px;padding:12px;background:var(--rust-dim);
    border-radius:9px;border:1px dashed var(--rust);}
  .wqm-scope .mortal-detail.show{display:block;}
  /* Isi grid secara bawaan punya min-width:auto sehingga MENOLAK menyusut di
     bawah lebar alaminya — tiga stepper lalu meluber keluar kartu. min-width:0
     mengizinkannya menyusut, dan auto-fit menurunkan jumlah kolom saat sempit
     alih-alih memaksakan tiga kolom. */
  .wqm-scope .row3{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px;}
  .wqm-scope .row3 > *{min-width:0;}
  .wqm-scope .row3 .stepper-wrap{flex-wrap:wrap;}

  .wqm-scope .output-card{background:var(--deep);color:#eaf7f6;border-radius:8px;padding:16px 18px;margin-bottom:14px;}
  .wqm-scope .output-card h3{margin:0 0 12px;padding-bottom:9px;border-bottom:1px solid rgba(255,255,255,.15);
    font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:#9fe3dc;font-family:var(--disp);font-weight:700;}
  .wqm-scope .output-card pre{white-space:pre-wrap;word-break:break-word;font-family:var(--mono);
    font-size:12.5px;line-height:1.7;background:rgba(255,255,255,.07);border-radius:6px;
    border:1px solid rgba(255,255,255,.12);
    padding:14px 16px;margin:0 0 14px;max-height:340px;overflow-y:auto;}
  .wqm-scope .out-actions{display:flex;gap:8px;flex-wrap:wrap;}
  .wqm-scope .out-actions button{padding:7px 12px;border-radius:6px;font-weight:700;cursor:pointer;
    background:rgba(255,255,255,.14);color:#eaf7f6;border:1px solid rgba(255,255,255,.25);}
  .wqm-scope .out-actions button:hover{background:rgba(255,255,255,.22);}
  .wqm-scope .out-actions button{flex:1;padding:8px;border-radius:8px;border:1px solid rgba(255,255,255,.3);
    background:rgba(255,255,255,.1);color:#fff;font-weight:700;font-size:12.5px;cursor:pointer;font-family:var(--body);}
  .wqm-scope .out-actions .wa{background:#25D366;border-color:#25D366;color:#06331b;}

  .wqm-scope table.mini{width:100%;border-collapse:collapse;font-size:12.5px;}
  .wqm-scope table.mini th{text-align:left;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;
    color:var(--muted);padding:6px;border-bottom:1.5px solid var(--line);}
  .wqm-scope table.mini td{padding:8px 6px;border-bottom:1px solid var(--line);vertical-align:top;}
  .wqm-scope table.mini tr:last-child td{border-bottom:none;}
  .wqm-scope .pill-del{background:#fdecea;color:var(--bad);border:none;padding:4px 8px;border-radius:6px;font-size:11px;font-weight:700;cursor:pointer;}
  .wqm-scope .pill-view{background:var(--rust-dim);color:var(--deep);border:none;padding:4px 8px;border-radius:6px;font-size:11px;font-weight:700;cursor:pointer;margin-right:4px;}
  .wqm-scope .empty-state{text-align:center;padding:24px 10px;color:var(--muted);font-size:13px;}

  .wqm-scope .add-row{display:flex;gap:8px;margin-top:8px;}
  .wqm-scope .add-row input{flex:1;}
  .wqm-scope .add-row button{background:var(--deep);color:#fff;border:none;border-radius:8px;padding:0 14px;font-weight:800;font-size:15px;cursor:pointer;}
  .wqm-scope .filter-row{display:flex;gap:8px;margin-bottom:12px;}
  .wqm-scope .filter-row select{flex:1;}

  /* Diperkecil (13px/14.5px/800 -> 10px/13.5px/700) mendekati .save-btn app
     lain (9px 16px/13px). */
  .wqm-scope .btn-primary{width:100%;background:var(--rust);
    color:#fff;border:none;padding:10px;border-radius:9px;font-size:13.5px;font-weight:700;cursor:pointer;font-family:var(--body);}
  .wqm-scope .btn-primary:disabled{opacity:.45;}
  .wqm-scope .btn-secondary{background:#fff;color:var(--deep);border:1.5px solid var(--line);
    padding:9px;border-radius:9px;font-size:13px;font-weight:700;cursor:pointer;font-family:var(--body);}

  /* Kartu satu-pond di Analisa Shrimp Health (07c) -- beberapa bisa muncul
     sekaligus dari satu unggahan PDF, tiap kartu wajib dipilih Kolam DFT-nya
     sendiri (nama pond dari PDF tidak sama skema dengan nama kolam DFT). */
  .wqm-scope .sh-pond-card{border:1px solid var(--line); border-radius:10px; padding:14px 14px 10px; margin-bottom:14px; background:var(--card); position:relative;}
  .wqm-scope .sh-pond-card .pill-del{position:absolute; top:10px; right:10px;}

  @keyframes wqmShake{0%,100%{transform:translateX(0)}20%{transform:translateX(-6px)}40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(4px)}}

  /* ═══ UTILITY ═══════════════════════════════════════════════════════════
     Pelengkap class komponen di atas, BUKAN penggantinya.

     Kenapa semuanya berawalan `u-`: nama generik seperti .grid, .row, .wrap,
     .fill, .left, .stat, .label, .value, .good, .bad, .warn SUDAH DIPAKAI di
     berkas ini dengan arti komponen tertentu. Utility tanpa awalan cepat atau
     lambat akan menimpanya, dan gejalanya muncul sebagai tata letak rusak di
     layar yang sedang tidak dikerjakan — jenis kerusakan yang paling lama
     ketahuan. Awalan membuat bentrokan mustahil, sekaligus langsung terlihat
     di markup mana yang utility dan mana yang komponen.

     Skala jarak mengikuti irama yang memang sudah dipakai di berkas ini
     (gap 8/12/16px, padding 10-20px):
       0 = 0     1 = 4px   2 = 8px   3 = 12px
       4 = 16px  5 = 20px  6 = 24px

     Ditaruh PALING BAWAH dengan sengaja: pada kekhususan (specificity) yang
     sama, aturan terakhir menang — jadi utility bisa menyesuaikan komponen,
     bukan sebaliknya.

     BATASNYA: kalau satu pola dipakai di lebih dari ~3 tempat, jadikan class
     komponen bernama di atas. Utility untuk penyesuaian setempat, bukan untuk
     merakit komponen baru dari nol — kalau dipakai begitu, markup jadi penuh
     dan justru lebih sulit dibaca daripada CSS yang digantikannya. */

  /* -- tampilan -- */
  .u-flex{display:flex;}
  .u-inline-flex{display:inline-flex;}
  .u-grid{display:grid;}
  .u-block{display:block;}
  .u-inline-block{display:inline-block;}
  .u-hidden{display:none;}

  /* -- arah & perataan flex -- */
  .u-col{flex-direction:column;}
  .u-flex-wrap{flex-wrap:wrap;}
  .u-flex-nowrap{flex-wrap:nowrap;}
  .u-items-start{align-items:flex-start;}
  .u-items-center{align-items:center;}
  .u-items-end{align-items:flex-end;}
  .u-items-baseline{align-items:baseline;}
  .u-justify-center{justify-content:center;}
  .u-justify-end{justify-content:flex-end;}
  .u-justify-between{justify-content:space-between;}
  /* min-width:0 disertakan sengaja: tanpa itu anak flex menolak menyusut di
     bawah lebar isinya, dan tabel/teks panjang membuat kartunya melebar
     keluar layar HP. Ini jebakan flexbox yang paling sering terjadi di sini. */
  .u-grow{flex:1 1 auto;min-width:0;}
  .u-shrink-0{flex-shrink:0;}

  /* -- jarak antar anak -- */
  .u-gap-0{gap:0;}
  .u-gap-1{gap:4px;}
  .u-gap-2{gap:8px;}
  .u-gap-3{gap:12px;}
  .u-gap-4{gap:16px;}
  .u-gap-5{gap:20px;}
  .u-gap-6{gap:24px;}

  /* -- margin -- */
  .u-m-0{margin:0;}
  .u-mt-0{margin-top:0;}
  .u-mt-1{margin-top:4px;}
  .u-mt-2{margin-top:8px;}
  .u-mt-3{margin-top:12px;}
  .u-mt-4{margin-top:16px;}
  .u-mt-5{margin-top:20px;}
  .u-mt-6{margin-top:24px;}
  .u-mb-0{margin-bottom:0;}
  .u-mb-1{margin-bottom:4px;}
  .u-mb-2{margin-bottom:8px;}
  .u-mb-3{margin-bottom:12px;}
  .u-mb-4{margin-bottom:16px;}
  .u-mb-5{margin-bottom:20px;}
  .u-mb-6{margin-bottom:24px;}
  .u-ml-auto{margin-left:auto;}
  .u-mr-auto{margin-right:auto;}
  .u-mx-auto{margin-left:auto;margin-right:auto;}

  /* -- padding -- */
  .u-p-0{padding:0;}
  .u-p-2{padding:8px;}
  .u-p-3{padding:12px;}
  .u-p-4{padding:16px;}
  .u-px-2{padding-left:8px;padding-right:8px;}
  .u-px-3{padding-left:12px;padding-right:12px;}
  .u-px-4{padding-left:16px;padding-right:16px;}
  .u-py-1{padding-top:4px;padding-bottom:4px;}
  .u-py-2{padding-top:8px;padding-bottom:8px;}
  .u-py-3{padding-top:12px;padding-bottom:12px;}

  /* -- teks -- */
  .u-text-left{text-align:left;}
  .u-text-center{text-align:center;}
  .u-text-right{text-align:right;}
  .u-text-xs{font-size:11px;}
  .u-text-sm{font-size:12px;}
  .u-text-md{font-size:13px;}
  .u-text-lg{font-size:15px;}
  .u-font-normal{font-weight:400;}
  .u-font-semibold{font-weight:600;}
  .u-font-bold{font-weight:700;}
  .u-font-black{font-weight:800;}
  .u-nowrap{white-space:nowrap;}
  .u-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
  /* Angka jadi selebar sama rata sehingga kolom desimal di tabel berbaris
     lurus — berguna di hampir semua tabel aplikasi ini yang penuh angka. */
  .u-tabular{font-variant-numeric:tabular-nums;}

  /* -- warna teks (memakai token yang sama dengan komponen) -- */
  .u-ink{color:var(--ink);}
  .u-muted{color:var(--muted);}
  .u-deep{color:var(--deep);}
  .u-rust{color:var(--rust);}
  .u-good{color:var(--good);}
  .u-warn{color:var(--warn);}
  .u-bad{color:var(--bad);}

  /* -- ukuran -- */
  .u-w-full{width:100%;}
  .u-max-w-full{max-width:100%;}

  /* -- lain-lain -- */
  .u-scroll-x{overflow-x:auto;}
  .u-border-top{border-top:1px solid var(--line);}
  .u-border-bottom{border-bottom:1px solid var(--line);}

  /* ---- Tabel Laba/Rugi (Dashboard) -----------------------------------
     Header memakai gradasi teal yang SAMA dengan tabel Ringkasan per Kolam,
     bukan gaya header baru: dua tabel keuangan berdampingan di satu layar
     dengan kepala berbeda akan terbaca seperti berasal dari dua aplikasi.

     Dekorasinya sengaja minim. Untuk laporan yang akan dibaca investor,
     kesan bisa-dipercaya datang dari kerapian angka, bukan dari hiasan. */
  table.lr-table{ width:100%; border-collapse:collapse; }
  table.lr-table thead tr{ background:linear-gradient(135deg,#0e4d63,#098089); }
  table.lr-table thead th{ color:#eef7f6; padding:9px 10px; font-size:11px; letter-spacing:.04em;
    text-transform:uppercase; font-weight:600; text-align:left; }
  table.lr-table thead th.num{ text-align:right; }
  table.lr-table tbody td{ padding:8px 10px; font-size:13px; border-bottom:1px solid var(--line); }
  table.lr-table tbody tr:nth-child(even){ background:#f6fbfa; }
  /* Semua angka rata kanan dan bertabular supaya digit satuan berjajar lurus
     antar-baris — inti keterbacaan sebuah laporan keuangan. */
  table.lr-table td.num, table.lr-table th.num{ text-align:right; font-family:var(--mono);
    font-variant-numeric:tabular-nums; white-space:nowrap; }
  table.lr-table tfoot tr.lr-total td{ padding:11px 10px; font-size:14px; font-weight:700;
    background:var(--sand); border-top:2px solid var(--deep); border-bottom:none; }

  /* ===== OBROLAN TIM — bubble chat ala WhatsApp/Telegram ===== */
  .chat-scope #chat-daftar{ background:var(--sand); border-radius:10px; padding:10px 8px; border:1px solid var(--line); }
  .chat-scope .chat-day-sep{ text-align:center; margin:10px 0; }
  .chat-scope .chat-day-sep span{ display:inline-block; background:var(--card); color:var(--muted);
    font-size:11px; font-weight:700; padding:3px 12px; border-radius:20px; border:1px solid var(--line); }
  .chat-scope .chat-sys{ text-align:center; font-size:11.5px; color:var(--muted); margin:8px 0; }
  .chat-scope .chat-sys-time{ opacity:.7; }
  .chat-scope .chat-row{ display:flex; align-items:flex-end; gap:8px; margin-top:2px; margin-bottom:2px; }
  .chat-scope .chat-row.mine{ flex-direction:row-reverse; }
  .chat-scope .chat-row-awal{ margin-top:10px; }
  .chat-scope .chat-avatar{ width:28px; height:28px; border-radius:50%; flex:none;
    display:flex; align-items:center; justify-content:center; color:#fff; font-size:12px; font-weight:700; visibility:hidden; }
  .chat-scope .chat-row-awal .chat-avatar{ visibility:visible; }
  .chat-scope .chat-bubble-wrap{ max-width:74%; display:flex; flex-direction:column; min-width:0; }
  .chat-scope .chat-row.mine .chat-bubble-wrap{ align-items:flex-end; }
  .chat-scope .chat-row.theirs .chat-bubble-wrap{ align-items:flex-start; }
  .chat-scope .chat-name{ font-size:11px; font-weight:700; margin:0 4px 2px; letter-spacing:.01em; }
  .chat-scope .chat-bubble{ padding:7px 10px 6px; border-radius:14px; box-shadow:0 1px 1px rgba(0,0,0,.06); max-width:100%; }
  .chat-scope .chat-bubble.theirs{ background:var(--card); border:1px solid var(--line); border-bottom-left-radius:3px; }
  .chat-scope .chat-bubble.mine{ background:var(--rust-dim); color:var(--ink); border-bottom-right-radius:3px; }
  .chat-scope .chat-teks{ white-space:pre-wrap; word-break:break-word; font-size:13.5px; line-height:1.4; }
  .chat-scope .chat-meta{ font-size:10px; color:var(--muted); text-align:right; margin-top:2px; opacity:.75; }
  .chat-scope .chat-reaksi-row{ display:flex; gap:4px; flex-wrap:wrap; align-items:center; margin-top:3px; }
  .chat-scope .chat-reaksi, .chat-scope .chat-reaksi-tambah{ background:var(--card); border:1px solid var(--line);
    color:var(--deep); padding:1px 7px; border-radius:20px; font-size:11px; font-weight:700; cursor:pointer; }
  .chat-scope .chat-reaksi-ikut{ background:var(--rust-dim); border-color:var(--rust); }
  .chat-scope .chat-reaksi-tambah{ opacity:.55; padding:1px 6px; }
  .chat-scope .chat-hapus{ background:none; border:none; color:var(--bad); font-size:11px; cursor:pointer; padding:1px 4px; }
  /* Bar input ala WA/Telegram: pil bulat + tombol kirim bundar. */
  .chat-scope .chat-input-bar{ display:flex; align-items:flex-end; gap:8px; margin-top:12px; }
  .chat-scope #chat-input{ flex:1; min-width:0; resize:none; border-radius:20px; padding:9px 16px;
    border:1px solid var(--line); background:var(--card); max-height:120px; }
  .chat-scope #chat-kirim{ flex:none; width:40px; height:40px; border-radius:50%; padding:0;
    display:flex; align-items:center; justify-content:center; font-size:16px; border:none;
    background:var(--deep); color:#fff; cursor:pointer; }
  .chat-scope #chat-kirim:disabled{ opacity:.5; cursor:not-allowed; }

  /* ===== Sapaan Header (kartu Pengaturan) — chip pilih preset/kustom ===== */
  .sapaan-pilih{display:flex;flex-wrap:wrap;gap:8px;}
  .sapaan-pilih .chip{border:1.5px solid var(--line);background:var(--sand);color:var(--muted);
    padding:8px 14px;border-radius:18px;font-size:13px;font-weight:600;cursor:pointer;font-family:var(--body);}
  .sapaan-pilih .chip.active{background:var(--deep);border-color:var(--deep);color:#fff;}
