:root{
  /* Tema terang: latar putih, aksen hijau, teks hitam. */
  --bg:#f4f7f5; --bg2:#ffffff; --card:#ffffff; --card2:#f7faf8;
  --line:#dde5e0; --line2:#c9d6ce;
  --txt:#111827; --muted:#5c6b63;
  --pri:#15803d;        /* hijau tombol — cukup gelap agar teks putih terbaca */
  --pri2:#16a34a;       /* hijau aksen */
  --pri3:#22c55e;       /* hijau cerah untuk sorotan */
  --tint:#e9f7ee;       /* latar hijau muda */
  --ok:#15803d; --warn:#b45309; --bad:#b91c1c;
  --r:14px;
}
*{box-sizing:border-box}
body{
  margin:0;font-family:"Segoe UI",system-ui,-apple-system,Roboto,sans-serif;
  background:var(--bg);color:var(--txt);min-height:100vh;-webkit-font-smoothing:antialiased;
}
a{color:var(--pri);text-decoration:none}
a:hover{text-decoration:underline}

/* ---------- layout ---------- */
.topbar{
  display:flex;align-items:center;gap:18px;padding:14px 22px;
  background:#fff;border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:50;flex-wrap:wrap;box-shadow:0 1px 3px rgba(17,24,39,.05);
}
.brand{display:flex;align-items:center;gap:10px;font-weight:800;letter-spacing:.3px;font-size:17px;color:var(--txt)}
.brand .dot{width:11px;height:11px;border-radius:50%;background:var(--pri3);box-shadow:0 0 0 4px var(--tint)}
.brand small{display:block;font-weight:500;font-size:11px;color:var(--muted);letter-spacing:0}
.nav{display:flex;gap:6px;margin-left:auto;flex-wrap:wrap}
.nav a{
  padding:8px 14px;border-radius:10px;color:var(--muted);font-size:14px;font-weight:600;
  border:1px solid transparent;transition:.15s;text-decoration:none
}
.nav a:hover{color:var(--txt);background:var(--tint);text-decoration:none}
.nav a.active{color:#fff;background:var(--pri);border-color:var(--pri)}

.apppicker{display:flex;align-items:center;gap:8px}
.apppicker .picker-label{margin:0;font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--muted)}
.apppicker select{
  width:auto;min-width:170px;padding:7px 11px;font-size:13.5px;font-weight:600;
  border-radius:9px;border:1px solid var(--pri2);background:#fff;color:var(--txt)
}
.wrap{max-width:1180px;margin:0 auto;padding:26px 20px 70px}

/* ---------- kartu ---------- */
.grid{display:grid;gap:16px}
.g4{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.g2{grid-template-columns:repeat(auto-fit,minmax(330px,1fr))}
.card{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:20px;
  box-shadow:0 1px 3px rgba(17,24,39,.06)
}
.card h2{margin:0 0 4px;font-size:16px;letter-spacing:.2px;color:var(--txt)}
.card .sub{color:var(--muted);font-size:13px;margin-bottom:16px}
.stat .label{color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:1px}
.stat .val{font-size:31px;font-weight:800;margin-top:6px;color:var(--pri)}
.stat .hint{color:var(--muted);font-size:12px;margin-top:4px}

/* ---------- form ---------- */
label{display:block;font-size:13px;font-weight:600;margin:14px 0 6px;color:var(--txt)}
label .tip{display:block;font-weight:400;color:var(--muted);font-size:12px;margin-top:3px}
input[type=text],input[type=password],input[type=number],textarea,select{
  width:100%;padding:11px 13px;border-radius:10px;border:1px solid var(--line2);
  background:#fff;color:var(--txt);font-size:14px;font-family:inherit;outline:none;transition:.15s
}
input:focus,textarea:focus,select:focus{border-color:var(--pri2);box-shadow:0 0 0 3px rgba(34,197,94,.2)}
textarea{min-height:110px;resize:vertical}
.row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.switch{display:flex;align-items:center;gap:10px;margin:12px 0;cursor:pointer}
.switch input{appearance:none;width:44px;height:24px;border-radius:20px;background:#cbd5d0;position:relative;cursor:pointer;transition:.2s;flex:none}
.switch input:checked{background:var(--pri2)}
.switch input::after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;transition:.2s;box-shadow:0 1px 2px rgba(0,0,0,.2)}
.switch input:checked::after{left:23px}
.switch span{font-size:14px}
.switch small{display:block;color:var(--muted);font-size:12px}

.btn{
  display:inline-flex;align-items:center;gap:7px;padding:11px 18px;border:0;border-radius:10px;
  background:var(--pri);color:#fff;font-weight:700;font-size:14px;
  cursor:pointer;transition:.15s;font-family:inherit
}
.btn:hover{background:var(--pri2);transform:translateY(-1px);text-decoration:none;color:#fff}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none}
.btn.ghost{background:#fff;border:1px solid var(--line2);color:var(--txt)}
.btn.ghost:hover{border-color:var(--pri2);background:var(--tint);color:var(--txt)}
.btn.sm{padding:7px 12px;font-size:12.5px;border-radius:8px}
.btn.danger{background:var(--bad)}
.btn.danger:hover{background:#dc2626}

/* ---------- badge & pill ---------- */
.badge{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:20px;font-size:11.5px;font-weight:700;letter-spacing:.3px}
.badge.on{background:var(--tint);color:#166534;border:1px solid #a7e3bd}
.badge.off{background:#fdecec;color:#b91c1c;border:1px solid #f4bcbc}
.badge.wait{background:#fdf3e3;color:#b45309;border:1px solid #f0d3a3}
.badge.info{background:#eef2f7;color:#334155;border:1px solid #cfd9e5}
.dotled{width:8px;height:8px;border-radius:50%;background:currentColor}

/* ---------- list pengumuman ---------- */
.ann{border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin-bottom:12px;background:var(--card2);transition:.15s}
.ann:hover{border-color:var(--pri3)}
.ann.pin{border-color:var(--pri2);background:var(--tint)}
.ann .head{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:8px}
.ann .title{font-weight:700;font-size:15px}
.ann .meta{color:var(--muted);font-size:12px;margin-left:auto}
.ann .body{font-size:14px;line-height:1.6;color:#26322c;word-break:break-word}
.ann .body img{max-width:100%;border-radius:8px}
.ann .thumb{max-width:190px;border-radius:8px;margin-top:10px;display:block}
.ann .acts{display:flex;gap:7px;margin-top:12px;flex-wrap:wrap}

/* ---------- misc ---------- */
.code{
  background:#f6f8f7;border:1px solid var(--line);border-radius:10px;padding:14px;
  font-family:"Fira Code",Consolas,monospace;font-size:12.5px;line-height:1.65;color:#1f2937;
  overflow-x:auto;white-space:pre;position:relative
}
.copy{position:absolute;top:8px;right:8px}
.empty{text-align:center;color:var(--muted);padding:40px 10px;font-size:14px}
.toast{
  position:fixed;right:20px;bottom:20px;z-index:200;background:#fff;
  border:1px solid var(--line2);border-left:4px solid var(--pri2);padding:13px 18px;border-radius:10px;
  box-shadow:0 8px 26px rgba(17,24,39,.16);font-size:14px;max-width:340px;animation:sl .25s ease;color:var(--txt)
}
.toast.bad{border-color:#f4bcbc;border-left-color:var(--bad)}
.toast.ok{border-color:#a7e3bd;border-left-color:var(--pri2)}
@keyframes sl{from{transform:translateY(14px);opacity:0}to{transform:none;opacity:1}}
hr{border:0;border-top:1px solid var(--line);margin:22px 0}
.mono{font-family:Consolas,monospace;font-size:13px}
.tabs{display:flex;gap:6px;margin-bottom:16px;flex-wrap:wrap}
.tabs button{padding:7px 14px;border-radius:20px;border:1px solid var(--line2);background:#fff;color:var(--muted);cursor:pointer;font-size:13px;font-weight:600;font-family:inherit}
.tabs button.active{background:var(--pri);color:#fff;border-color:var(--pri)}
table{width:100%;border-collapse:collapse;font-size:13px}
th,td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--line)}
th{color:var(--muted);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.5px}

/* ---------- login ---------- */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;
  background:linear-gradient(160deg,var(--tint) 0%,var(--bg) 55%)}
.login-box{width:100%;max-width:400px;background:#fff;
  border:1px solid var(--line);border-radius:18px;padding:34px;box-shadow:0 10px 34px rgba(17,24,39,.10)}
.login-box .logo{text-align:center;margin-bottom:24px}
.login-box .logo h1{margin:10px 0 4px;font-size:23px;letter-spacing:.5px;color:var(--txt)}
.login-box .logo p{margin:0;color:var(--muted);font-size:13px}
.login-box .btn{width:100%;justify-content:center;margin-top:20px;padding:13px}
.err{background:#fdecec;border:1px solid #f4bcbc;color:#b91c1c;
  padding:10px 13px;border-radius:9px;font-size:13px;margin-top:14px;display:none}


/* ---------- indikator sedang berjalan ----------
   Tombol yang cuma redup tidak memberi tahu apa pun: pengguna mengira macet.
   Semua aksi yang butuh waktu memakai pemintal atau bilah kemajuan. */
.spin{
  width:14px;height:14px;flex:none;border-radius:50%;display:inline-block;
  border:2px solid rgba(255,255,255,.35);border-top-color:#fff;
  animation:putar .7s linear infinite
}
.btn.ghost .spin,.spin.gelap{border-color:rgba(17,24,39,.2);border-top-color:var(--pri)}
.spin.besar{width:22px;height:22px;border-width:3px}
@keyframes putar{to{transform:rotate(360deg)}}

.progres{height:6px;border-radius:99px;background:var(--line);overflow:hidden}
.progres > i{display:block;height:100%;width:0;border-radius:99px;
  background:linear-gradient(90deg,var(--pri),var(--pri3));transition:width .25s ease}
/* Tanpa persentase yang bisa dihitung (mis. build Gradle): bilah berjalan. */
.progres.tak-tentu > i{width:38%;animation:geser 1.2s ease-in-out infinite}
@keyframes geser{0%{margin-left:-38%}100%{margin-left:100%}}

.drop{position:relative}
.drop.sibuk{pointer-events:none}
.drop .tirai{
  position:absolute;inset:0;background:var(--card2);border-radius:10px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;
  font-size:12.5px;font-weight:600;padding:12px
}
.drop .tirai .progres{width:80%;max-width:200px}

.kerja{
  display:flex;align-items:center;gap:12px;padding:13px 15px;margin-top:14px;
  border:1px solid var(--pri2);border-radius:12px;background:var(--tint)
}
.kerja .isi{flex:1;min-width:0}
.kerja .judul{font-weight:700;font-size:13.5px}
.kerja .tahap{font-size:12px;color:var(--muted);margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kerja .jam{font-variant-numeric:tabular-nums;font-weight:700;font-size:13px;color:var(--pri)}
