/* ---------- Design tokens — soft monochrome (B&W) palette ---------- */
:root{
  /* surface (warm-tinted off-white) */
  --bg: oklch(0.975 0.003 80);
  --bg-2: oklch(0.96 0.004 80);
  --surface: #ffffff;
  --surface-2: oklch(0.975 0.003 80);
  --border: oklch(0.91 0.004 80);
  --border-2: oklch(0.95 0.003 80);

  /* ink (soft graphite) */
  --ink: oklch(0.22 0.005 80);
  --ink-2: oklch(0.42 0.004 80);
  --ink-3: oklch(0.58 0.004 80);
  --ink-4: oklch(0.74 0.003 80);

  /* primary — soft graphite / charcoal */
  --primary: oklch(0.30 0.006 80);
  --primary-hover: oklch(0.22 0.006 80);
  --primary-tint: oklch(0.94 0.004 80);
  --primary-ring: oklch(0.82 0.004 80);
  --primary-deep: oklch(0.16 0.006 80);

  /* status — desaturated, subtle */
  --success: oklch(0.62 0.07 150);
  --success-tint: oklch(0.95 0.025 150);
  --warning: oklch(0.72 0.09 70);
  --warning-tint: oklch(0.96 0.035 70);
  --danger: oklch(0.62 0.10 25);
  --danger-tint: oklch(0.96 0.03 25);
  --neutral-tint: oklch(0.94 0.003 80);

  --success-ink: oklch(0.42 0.07 150);
  --warning-ink: oklch(0.46 0.10 70);
  --danger-ink: oklch(0.44 0.11 25);

  /* accents */
  --accent-gold: oklch(0.55 0.005 80);
  --accent-amber: oklch(0.42 0.005 80);

  /* grid pattern */
  --grid-stroke: oklch(0.91 0.004 80 / .6);
  --grid-dot: oklch(0.80 0.005 80 / .55);

  /* shadows */
  --shadow-1: 0 1px 2px rgba(20,20,22,.04), 0 1px 1px rgba(20,20,22,.03);
  --shadow-2: 0 8px 22px -10px rgba(20,20,22,.16), 0 2px 6px -2px rgba(20,20,22,.06);
  --shadow-3: 0 24px 60px -18px rgba(20,20,22,.28), 0 6px 16px -6px rgba(20,20,22,.08);

  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;
  --radius-xl: 22px;
}

*,*::before,*::after{box-sizing:border-box}
html,body,#root{height:100%}
body{
  margin:0;
  font-family:"Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
  font-size:14px;
  color:var(--ink);
  background:var(--bg);
  background-image:
    linear-gradient(var(--grid-stroke) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-stroke) 1px, transparent 1px);
  background-size: 32px 32px, 32px 32px;
  background-position: -1px -1px;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:inherit;color:inherit}
.mono{font-family:"JetBrains Mono", ui-monospace, monospace; font-feature-settings:"tnum"}
.tnum{font-feature-settings:"tnum"}

/* ---------- App shell ---------- */
.app{
  display:grid;
  grid-template-columns: 248px 1fr;
  height:100vh;
  background:transparent;
  overflow:hidden;
}
.sidebar{
  background:linear-gradient(180deg, oklch(0.985 0.003 80) 0%, oklch(0.965 0.004 80) 100%);
  border-right:1px solid var(--border);
  display:flex; flex-direction:column;
  padding:18px 14px;
  position:relative;
}
.brand{
  display:flex; align-items:center; gap:10px;
  padding:6px 8px 18px 8px;
  border-bottom:1px solid var(--border-2);
  margin-bottom:12px;
}
.brand-mark{
  width:42px; height:42px; border-radius:11px;
  background:white;
  display:grid; place-items:center; color:white;
  box-shadow: 0 8px 18px -6px rgba(20,20,22,.18), inset 0 0 0 1px var(--border);
  position:relative; overflow:hidden;
  animation: brandFloat 5s ease-in-out infinite;
  flex-shrink:0;
}
.brand-mark img{width:100%; height:100%; object-fit:contain; padding:3px}
@keyframes brandFloat{
  0%,100%{transform:translateY(0) rotate(0deg)}
  50%{transform:translateY(-2px) rotate(-2deg)}
}
.brand-mark::after{
  content:""; position:absolute; inset:-50% -50%;
  background:radial-gradient(circle at 30% 30%, rgba(255,255,255,.35), transparent 50%);
}
.brand-text{display:flex; flex-direction:column; line-height:1.15}
.brand-text b{font-size:15px; font-weight:700; letter-spacing:-0.01em}
.brand-text span{font-size:11px; color:var(--ink-3); font-weight:500}

.nav-section-label{
  font-size:11px; font-weight:600; color:var(--ink-4); letter-spacing:0.06em;
  text-transform:uppercase; padding:14px 10px 6px;
}
.nav-item{
  display:flex; align-items:center; gap:11px;
  padding:10px 12px; margin:1px 0;
  border-radius:10px; color:var(--ink-2);
  font-weight:500; font-size:13.5px;
  cursor:pointer;
  transition: background .18s ease, color .18s ease, transform .18s ease;
  position:relative;
}
.nav-item:hover{background:var(--surface-2); color:var(--ink)}
.nav-item.active{
  background:var(--primary-tint);
  color:var(--primary-hover);
  font-weight:600;
}
.nav-item.active::before{
  content:""; position:absolute; left:-14px; top:8px; bottom:8px; width:3px;
  background:var(--primary); border-radius:0 3px 3px 0;
}
.nav-item svg{flex-shrink:0}
.nav-item .badge-dot{
  margin-left:auto; width:6px; height:6px; border-radius:50%; background:var(--success);
  box-shadow:0 0 0 3px oklch(0.66 0.11 155 / .15);
}

.sidebar-footer{
  margin-top:auto; padding-top:14px; border-top:1px solid var(--border-2);
}
.nav-item{transform-origin:left center}
.nav-item:hover{transform:translateX(2px)}
.nav-item.active::before{animation: navAccent .4s cubic-bezier(.2,.7,.2,1) both}
@keyframes navAccent{from{transform:scaleY(0)} to{transform:scaleY(1)}}
.user-card{
  display:flex; align-items:center; gap:10px;
  padding:8px; border-radius:12px;
  background:var(--surface);
  border:1px solid var(--border-2);
}
.avatar{
  width:34px; height:34px; border-radius:50%;
  display:grid; place-items:center;
  background:linear-gradient(135deg, oklch(0.40 0.005 80), oklch(0.22 0.006 80));
  color:white; font-weight:700; font-size:12px;
  flex-shrink:0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.15);
}
.user-card .meta{flex:1; min-width:0}
.user-card .meta b{display:block; font-size:13px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.user-card .meta span{font-size:11px; color:var(--ink-3)}

/* ---------- Main / topbar ---------- */
.main{
  display:flex; flex-direction:column;
  min-width:0; overflow:hidden;
}
.topbar{
  display:flex; align-items:center; gap:14px;
  padding:14px 28px;
  background:rgba(255,255,255,.65);
  backdrop-filter: blur(8px);
  border-bottom:1px solid var(--border);
}
.topbar h1{
  margin:0; font-size:20px; font-weight:700; letter-spacing:-0.015em;
}
.topbar .crumb{font-size:12px; color:var(--ink-3); font-weight:500}
.topbar-spacer{flex:1}
.topbar-actions{display:flex; align-items:center; gap:10px}

.search{
  display:flex; align-items:center; gap:8px;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:10px;
  padding:8px 12px;
  width:260px;
  transition: border-color .15s, box-shadow .15s;
}
.search:focus-within{border-color:var(--primary-ring); box-shadow:0 0 0 3px var(--primary-tint)}
.search input{border:none; outline:none; background:none; flex:1; font-size:13px}
.search input::placeholder{color:var(--ink-4)}

.icon-btn{
  width:36px; height:36px; border-radius:10px;
  display:grid; place-items:center;
  background:var(--surface); border:1px solid var(--border);
  color:var(--ink-2);
  transition: background .15s, color .15s, transform .15s;
  position:relative;
}
.icon-btn:hover{background:var(--surface-2); color:var(--ink)}
.icon-btn .ping{
  position:absolute; top:7px; right:7px;
  width:7px; height:7px; border-radius:50%;
  background:var(--danger);
  box-shadow:0 0 0 3px var(--surface);
}

.btn{
  display:inline-flex; align-items:center; gap:8px;
  padding:9px 14px; border-radius:10px;
  font-weight:600; font-size:13px;
  transition: background .15s, color .15s, transform .12s, box-shadow .15s;
  border:1px solid transparent;
  white-space:nowrap;
}
.btn:active{transform:translateY(1px)}
.btn-primary{
  background:linear-gradient(180deg, var(--primary) 0%, var(--primary-hover) 100%);
  color:white;
  box-shadow: 0 8px 18px -6px rgba(20,20,22,.35), inset 0 1px 0 rgba(255,255,255,.12);
  position:relative; overflow:hidden;
}
.btn-primary::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(120deg, transparent 30%, rgba(255,255,255,.20) 50%, transparent 70%);
  transform:translateX(-120%); transition: transform .6s ease;
}
.btn-primary:hover::after{transform:translateX(120%)}
.btn-primary:hover{box-shadow: 0 10px 24px -6px rgba(20,20,22,.45)}
.btn-ghost{background:var(--surface); border-color:var(--border); color:var(--ink-2)}
.btn-ghost:hover{background:var(--surface-2); color:var(--ink)}
.btn-soft{background:var(--primary-tint); color:var(--primary-hover)}
.btn-soft:hover{background:oklch(0.92 0.04 265)}

/* ---------- Content ---------- */
.content{
  flex:1; overflow-y:auto; overflow-x:hidden;
  padding:24px 28px 60px;
  scroll-behavior:smooth;
  background:
    radial-gradient(900px 600px at 100% -10%, rgba(255,255,255,.6), transparent 60%),
    radial-gradient(700px 500px at -10% 100%, rgba(255,255,255,.5), transparent 60%);
  background-attachment: local;
}
.content > * + *{margin-top:18px}

.page-fade{animation: pageIn .42s cubic-bezier(.2,.7,.2,1) both}
@keyframes pageIn{
  from{opacity:0; transform:translateY(8px)}
  to{opacity:1; transform:none}
}

/* ---------- Cards ---------- */
.card{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-1);
}
.card-pad{padding:20px}
.card-head{
  padding:16px 20px;
  display:flex; align-items:center; gap:12px;
  border-bottom:1px solid var(--border-2);
}
.card-head h3{margin:0; font-size:15px; font-weight:700; letter-spacing:-0.01em}
.card-head .sub{font-size:12px; color:var(--ink-3); font-weight:500}

/* ---------- Metric cards ---------- */
.metric-row{
  display:grid; grid-template-columns: repeat(4, 1fr); gap:16px;
}
.metric{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  padding:18px 20px;
  position:relative; overflow:hidden;
  transition: transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s ease, border-color .25s;
  animation: metricIn .55s cubic-bezier(.2,.7,.2,1) both;
}
.metric:hover{transform:translateY(-3px); box-shadow:var(--shadow-2); border-color:var(--primary-ring)}
.metric:nth-child(1){animation-delay:.05s}
.metric:nth-child(2){animation-delay:.12s}
.metric:nth-child(3){animation-delay:.19s}
.metric:nth-child(4){animation-delay:.26s}
@keyframes metricIn{
  from{opacity:0; transform:translateY(14px) scale(.97)}
  to{opacity:1; transform:none}
}
.metric .label{
  font-size:12.5px; color:var(--ink-3); font-weight:600;
  display:flex; align-items:center; gap:8px;
}
.metric .value{
  font-size:36px; font-weight:800; letter-spacing:-0.02em;
  margin-top:8px; line-height:1;
  font-variant-numeric: tabular-nums;
}
.metric .foot{
  margin-top:10px; display:flex; align-items:center; gap:6px;
  font-size:12px; color:var(--ink-3);
}
.metric .foot .delta{
  font-weight:600; padding:2px 7px; border-radius:999px;
}
.metric .foot .delta.up{background:var(--success-tint); color:var(--success-ink)}
.metric .foot .delta.down{background:var(--danger-tint); color:oklch(0.50 0.13 20)}
.metric-icon{
  width:34px; height:34px; border-radius:10px;
  display:grid; place-items:center;
  position:absolute; top:18px; right:18px;
}
.metric.success .metric-icon{background:var(--success-tint); color:var(--success-ink)}
.metric.warning .metric-icon{background:var(--warning-tint); color:var(--warning-ink)}
.metric.danger  .metric-icon{background:var(--danger-tint);  color:oklch(0.50 0.13 20)}
.metric.primary .metric-icon{background:var(--primary-tint); color:var(--primary-hover)}
.metric.info    .metric-icon{background:oklch(0.94 0.04 235); color:oklch(0.42 0.14 240)}
.metric.purple  .metric-icon{background:oklch(0.94 0.04 305); color:oklch(0.42 0.14 295)}
.metric.success .value{color:var(--success-ink)}
.metric.warning .value{color:var(--warning-ink)}
.metric.danger  .value{color:var(--danger-ink)}
.metric.primary .value{color:var(--primary-hover)}
.metric.info    .value{color:oklch(0.42 0.14 240)}
.metric.purple  .value{color:oklch(0.42 0.14 295)}

/* 6-kartu layout di halaman Laporan (Hadir/Terlambat/Sakit/Izin/Alpha/%).
   Override default 4-col grid. Auto-wrap di tablet, 2-col di mobile. */
.metric-row.metric-row-6{
  grid-template-columns: repeat(6, 1fr);
}
@media (max-width: 1280px) {
  .metric-row.metric-row-6{grid-template-columns: repeat(3, 1fr)}
}
@media (max-width: 720px) {
  .metric-row.metric-row-6{grid-template-columns: repeat(2, 1fr)}
}

.metric::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px;
  background: linear-gradient(90deg, transparent, currentColor, transparent);
  opacity:.0;
}

/* ---------- Badges / chips ---------- */
.badge{
  display:inline-flex; align-items:center; gap:6px;
  padding:3px 10px; border-radius:999px;
  font-size:11.5px; font-weight:600;
  background:var(--neutral-tint); color:var(--ink-2);
}
.badge .dot{width:6px; height:6px; border-radius:50%; background:currentColor}
.badge.success{background:var(--success-tint); color:var(--success-ink)}
.badge.warning{background:var(--warning-tint); color:var(--warning-ink)}
.badge.danger{background:var(--danger-tint); color:oklch(0.50 0.13 20)}
.badge.primary{background:var(--primary-tint); color:var(--primary-hover)}
.badge.muted{background:var(--neutral-tint); color:var(--ink-3)}
/* izin → purple, sakit → info-blue. Konvensi rapor SMP: H/T merah-kuning
   untuk masalah, S/I biru-ungu netral (di-rapor), A merah (alpha). */
.badge.info{background:oklch(0.94 0.04 235); color:oklch(0.42 0.14 240)}
.badge.purple{background:oklch(0.94 0.04 305); color:oklch(0.42 0.14 295)}

/* Status radio chip — used in _status_modal.html so admin picks izin/sakit
   from large colored chips instead of a tiny radio button. */
.status-chip{
  display:inline-flex; align-items:center; gap:8px;
  padding:10px 16px;
  background:var(--surface-2);
  border:1px solid var(--border);
  border-radius:10px;
  font-size:13px; font-weight:600;
  cursor:pointer;
  transition:background .12s, border-color .12s;
}
.status-chip:hover{background:var(--surface-3, var(--surface-2))}
.status-chip .dot{width:8px; height:8px; border-radius:50%}
.status-chip.is-active.info  {background:oklch(0.94 0.04 235); border-color:oklch(0.55 0.18 240); color:oklch(0.42 0.14 240)}
.status-chip.is-active.purple{background:oklch(0.94 0.04 305); border-color:oklch(0.55 0.18 295); color:oklch(0.42 0.14 295)}

/* Keterangan dari admin (alasan izin/sakit) tampil di bawah status badge.
   Truncate dengan ellipsis kalau panjang; tooltip browser nya tetap kebaca. */
.ket-text{
  font-size:11px;
  color:var(--ink-3);
  font-style:italic;
  max-width:200px;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  line-height:1.3;
}

.device-pill{
  display:inline-flex; align-items:center; gap:8px;
  padding:6px 12px 6px 10px;
  background:var(--success-tint); color:var(--success-ink);
  border-radius:999px; font-size:12px; font-weight:600;
  border:1px solid oklch(0.85 0.08 140 / .5);
}
.device-pill .live{
  width:8px; height:8px; border-radius:50%; background:var(--success);
  box-shadow:0 0 0 0 oklch(0.66 0.11 155 / .5);
  animation: liveDot 1.8s ease-out infinite;
}
@keyframes liveDot{
  0%{box-shadow:0 0 0 0 oklch(0.66 0.11 155 / .55)}
  70%{box-shadow:0 0 0 8px oklch(0.66 0.11 155 / 0)}
  100%{box-shadow:0 0 0 0 oklch(0.66 0.11 155 / 0)}
}

/* ---------- Table ---------- */
.table-wrap{overflow:auto}
table.data{
  width:100%; border-collapse:collapse;
  font-size:13px;
}
table.data th{
  text-align:left; font-weight:600; font-size:11.5px; color:var(--ink-3);
  letter-spacing:0.04em; text-transform:uppercase;
  padding:11px 16px; border-bottom:1px solid var(--border-2);
  background:var(--surface);
  position:sticky; top:0; z-index:1;
}
table.data td{
  padding:12px 16px; border-bottom:1px solid var(--border-2);
  vertical-align:middle;
}
table.data tbody tr{transition: background .12s; animation: rowIn .45s cubic-bezier(.2,.7,.2,1) both}
table.data tbody tr:nth-child(1){animation-delay:.04s}
table.data tbody tr:nth-child(2){animation-delay:.08s}
table.data tbody tr:nth-child(3){animation-delay:.12s}
table.data tbody tr:nth-child(4){animation-delay:.16s}
table.data tbody tr:nth-child(5){animation-delay:.2s}
table.data tbody tr:nth-child(n+6){animation-delay:.24s}
table.data tbody tr:hover{background:var(--surface-2)}
@keyframes rowIn{from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:none}}
table.data tbody tr:last-child td{border-bottom:none}
.row-num{color:var(--ink-4); font-weight:500}

.student-cell{display:flex; align-items:center; gap:10px}
.student-cell .avatar{width:30px; height:30px; font-size:11px}
.student-cell b{font-weight:600; font-size:13px}

/* ---------- Tabs ---------- */
.tabs{
  display:inline-flex; gap:2px;
  background:var(--surface-2); padding:4px;
  border-radius:12px; border:1px solid var(--border-2);
}
.tab{
  padding:7px 14px; border-radius:9px;
  font-size:13px; font-weight:600; color:var(--ink-2);
  transition: background .2s, color .2s;
}
.tab:hover{color:var(--ink)}
.tab.active{background:var(--surface); color:var(--ink); box-shadow:var(--shadow-1)}

/* ---------- Chart ---------- */
.bar-chart{
  display:flex; align-items:flex-end; gap:10px;
  height:220px; padding:8px 4px 0;
}
.bar-group{
  flex:1; display:flex; gap:3px; align-items:flex-end; justify-content:center;
  position:relative;
}
.bar{
  width:14px; border-radius:6px 6px 2px 2px;
  transform-origin: bottom;
  animation: barGrow .8s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes barGrow{from{transform:scaleY(0)} to{transform:scaleY(1)}}
.bar.hadir{background: linear-gradient(180deg, var(--success), oklch(0.50 0.07 150))}
.bar.terlambat{background: linear-gradient(180deg, var(--warning), oklch(0.56 0.09 70))}
.bar.alpha{background: linear-gradient(180deg, var(--danger), oklch(0.50 0.10 25))}
.bar-axis{
  display:flex; padding-top:8px; border-top:1px solid var(--border-2);
}
.bar-axis div{flex:1; text-align:center; font-size:11px; color:var(--ink-3); font-weight:600}
.legend{display:flex; gap:14px; font-size:12px; color:var(--ink-2)}
.legend span{display:inline-flex; align-items:center; gap:6px}
.legend i{width:10px; height:10px; border-radius:3px; display:inline-block}

/* ---------- Toggle / switch ---------- */
.switch{
  position:relative; width:38px; height:22px; border-radius:999px;
  background:oklch(0.88 0.01 260); transition: background .2s;
  cursor:pointer; flex-shrink:0;
}
.switch::after{
  content:""; position:absolute; top:2px; left:2px;
  width:18px; height:18px; border-radius:50%; background:white;
  box-shadow:0 2px 4px rgba(0,0,0,.18);
  transition: transform .22s cubic-bezier(.4,1.4,.5,1);
}
.switch.on{background:var(--primary)}
.switch.on::after{transform:translateX(16px)}

/* ---------- Input ---------- */
.field{display:flex; flex-direction:column; gap:6px}
.field label{font-size:12px; font-weight:600; color:var(--ink-2)}
.input,.select{
  width:100%; padding:10px 12px; border-radius:10px;
  border:1px solid var(--border); background:var(--surface);
  font-size:13.5px; color:var(--ink);
  transition: border-color .15s, box-shadow .15s;
  outline:none;
}
.input:focus,.select:focus{border-color:var(--primary-ring); box-shadow:0 0 0 3px var(--primary-tint)}
.input::placeholder{color:var(--ink-4)}

/* ---------- Schedule timeline ---------- */
.timeline{
  position:relative; height:14px; border-radius:999px;
  background:var(--neutral-tint); overflow:hidden;
  display:flex;
  border:1px solid var(--border-2);
}
.timeline .seg{height:100%; transition: width .6s cubic-bezier(.2,.7,.2,1)}
.seg.hadir{background:var(--success)}
.seg.late{background:var(--warning)}
.seg.alpha{background:var(--danger)}
.seg.pulang{background:var(--primary)}
.tick-row{
  display:flex; justify-content:space-between; padding:0 2px;
  font-size:10.5px; color:var(--ink-4); margin-top:6px; font-family:"JetBrains Mono", monospace;
}

/* ---------- Modal ---------- */
.modal-backdrop{
  position:fixed; inset:0; background:oklch(0.20 0.02 265 / .35);
  backdrop-filter:blur(4px);
  display:grid; place-items:center;
  z-index:50;
  animation: fadeIn .2s ease both;
}
@keyframes fadeIn{from{opacity:0} to{opacity:1}}
.modal{
  background:var(--surface); border-radius:var(--radius-xl);
  width:min(680px, calc(100vw - 32px));
  max-height:calc(100vh - 60px);
  overflow:auto;
  box-shadow:var(--shadow-3);
  border:1px solid var(--border);
  animation: modalIn .35s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes modalIn{
  from{opacity:0; transform:translateY(14px) scale(.98)}
  to{opacity:1; transform:none}
}
.modal-head{padding:20px 22px 8px; display:flex; align-items:flex-start; justify-content:space-between}
.modal-head h3{margin:0; font-size:17px; font-weight:700; letter-spacing:-0.01em}
.modal-head p{margin:4px 0 0; font-size:12.5px; color:var(--ink-3)}
.modal-body{padding:16px 22px}
.modal-foot{
  padding:14px 22px 20px;
  display:flex; justify-content:flex-end; gap:10px;
  border-top:1px solid var(--border-2);
  background:linear-gradient(180deg, transparent, oklch(0.985 0.005 265 / .6));
}

/* ---------- RFID scanner ---------- */
.rfid-scan{
  position:relative;
  border:1.5px dashed var(--primary-ring);
  background: linear-gradient(180deg, var(--primary-tint), oklch(0.97 0.02 265));
  border-radius:14px;
  padding:18px;
  display:flex; align-items:center; gap:14px;
  overflow:hidden;
}
.rfid-pulse{
  width:54px; height:54px; flex-shrink:0;
  border-radius:50%;
  background:var(--surface);
  display:grid; place-items:center;
  color:var(--primary);
  position:relative;
  box-shadow:0 0 0 1px var(--primary-ring);
}
.rfid-pulse::before, .rfid-pulse::after{
  content:""; position:absolute; inset:0; border-radius:50%;
  border:2px solid var(--primary);
  animation: rfidPulse 1.8s ease-out infinite;
}
.rfid-pulse::after{animation-delay:.9s}
@keyframes rfidPulse{
  0%{transform:scale(1); opacity:.6}
  100%{transform:scale(2.2); opacity:0}
}

/* ---------- Parent portal ---------- */
.parent-wrap{
  min-height:100vh; width:100%;
  display:flex; align-items:center; justify-content:center;
  padding:40px 20px;
  background:
    radial-gradient(1100px 700px at 80% -10%, oklch(0.96 0.004 80 / .9), transparent 60%),
    radial-gradient(900px 600px at -10% 100%, oklch(0.94 0.005 80 / .85), transparent 60%),
    linear-gradient(180deg, oklch(0.985 0.003 80), oklch(0.95 0.004 80));
  background-image:
    linear-gradient(var(--grid-stroke) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-stroke) 1px, transparent 1px),
    radial-gradient(1100px 700px at 80% -10%, oklch(0.96 0.004 80 / .9), transparent 60%),
    radial-gradient(900px 600px at -10% 100%, oklch(0.94 0.005 80 / .85), transparent 60%),
    linear-gradient(180deg, oklch(0.985 0.003 80), oklch(0.95 0.004 80));
  background-size: 32px 32px, 32px 32px, auto, auto, auto;
  position:relative; overflow:hidden;
}
.parent-wrap::before, .parent-wrap::after{
  content:""; position:absolute; border-radius:50%;
  filter:blur(50px); opacity:.5; pointer-events:none;
}
.parent-wrap::before{
  width:420px; height:420px; left:-120px; top:8%;
  background:radial-gradient(circle, oklch(0.86 0.005 80), transparent 65%);
  animation: floaty 13s ease-in-out infinite;
}
.parent-wrap::after{
  width:340px; height:340px; right:-100px; bottom:5%;
  background:radial-gradient(circle, oklch(0.88 0.004 80), transparent 65%);
  animation: floaty 15s ease-in-out infinite reverse;
}
@keyframes floaty{
  0%,100%{transform:translate(0,0)}
  50%{transform:translate(20px, -20px)}
}
.parent-card{
  width:100%; max-width:460px;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:24px;
  padding:32px;
  box-shadow:var(--shadow-3);
  position:relative; z-index:1;
  animation: pageIn .5s cubic-bezier(.2,.7,.2,1) both;
}
.school-mark{
  width:88px; height:88px; border-radius:22px;
  background:white;
  display:grid; place-items:center;
  box-shadow:0 16px 36px -10px rgba(20,20,22,.25), inset 0 0 0 1px var(--border);
  margin:0 auto 16px;
  position:relative;
  animation: brandFloat 5s ease-in-out infinite;
  padding:6px;
}
.school-mark img{width:100%; height:100%; object-fit:contain}
.school-marks{
  display:flex; align-items:center; justify-content:center;
  gap:18px; margin-bottom:18px;
}
.school-marks .sep{
  width:1px; height:48px; background:var(--border);
}
.school-marks .school-mark{margin:0; animation:none}
.school-mark.govt{
  width:76px; height:76px; border-radius:18px;
  background:transparent; box-shadow:none;
  animation: brandFloat 5.5s ease-in-out infinite -1s;
}
.school-mark.govt img{padding:0}
.school-mark::before{
  content:""; position:absolute; inset:-8px; border-radius:26px;
  border:1.5px solid var(--primary-ring); opacity:.4;
  animation: ringPulse 2.6s ease-out infinite;
}
.school-mark.govt::before{display:none}
@keyframes ringPulse{
  0%{transform:scale(.92); opacity:.45}
  70%{transform:scale(1.25); opacity:0}
  100%{transform:scale(1.25); opacity:0}
}
.parent-card h1{
  text-align:center; margin:0 0 6px;
  font-size:22px; font-weight:700; letter-spacing:-0.02em;
}
.parent-card .lead{text-align:center; color:var(--ink-3); font-size:13.5px; margin:0 0 22px}

.feature-pills{display:flex; gap:8px; flex-wrap:wrap; justify-content:center; margin-top:18px}
.feature-pills .badge{padding:6px 12px; font-size:12px}

.portal-toggle{
  position:fixed; bottom:20px; right:20px;
  background:var(--surface); border:1px solid var(--border);
  border-radius:999px; padding:5px;
  box-shadow:var(--shadow-2);
  z-index:30;
  display:flex; gap:2px;
  animation: pageIn .5s .3s ease-out both;
}
.portal-toggle button{
  padding:8px 14px; border-radius:999px;
  font-size:12px; font-weight:600; color:var(--ink-3);
  transition: background .25s, color .25s, transform .15s;
  display:inline-flex; align-items:center; gap:6px;
}
.portal-toggle button:hover{color:var(--ink)}
.portal-toggle button.active{
  background:linear-gradient(180deg, var(--primary) 0%, var(--primary-hover) 100%);
  color:white;
  box-shadow: 0 6px 14px -4px rgba(20,20,22,.35);
}

/* ---------- Parent detail ---------- */
.parent-detail{
  width:100%; max-width:560px;
  display:flex; flex-direction:column; gap:14px;
  position:relative; z-index:1;
  animation: pageIn .5s cubic-bezier(.2,.7,.2,1) both;
}
.parent-detail .profile{
  background:var(--surface); border:1px solid var(--border);
  border-radius:20px; padding:18px;
  display:flex; align-items:center; gap:14px;
  box-shadow:var(--shadow-2);
}
.parent-detail .profile .avatar{width:54px; height:54px; font-size:18px}
.profile-info{flex:1; min-width:0}
.profile-info b{font-size:16px; font-weight:700; letter-spacing:-0.01em; display:block}
.profile-info span{font-size:12.5px; color:var(--ink-3)}

.tabbar{
  display:flex; gap:2px; padding:4px;
  background:var(--surface); border:1px solid var(--border);
  border-radius:14px; overflow:hidden;
}
.tabbar button{
  flex:1; padding:9px 8px; border-radius:10px;
  font-size:12.5px; font-weight:600; color:var(--ink-3);
  transition: background .2s, color .2s;
}
.tabbar button.active{
  background:var(--primary-tint); color:var(--primary-hover);
}

.status-hero{
  background:var(--surface); border:1px solid var(--border);
  border-radius:20px; padding:28px; text-align:center;
  box-shadow:var(--shadow-2);
  position:relative; overflow:hidden;
}
.status-hero .ring{
  width:96px; height:96px; border-radius:50%;
  margin:0 auto 14px; display:grid; place-items:center;
  position:relative;
}
.status-hero .ring.success{background:var(--success-tint); color:var(--success-ink)}
.status-hero .ring.warning{background:var(--warning-tint); color:var(--warning-ink)}
.status-hero .ring.info   {background:oklch(0.94 0.04 235); color:oklch(0.42 0.14 240)}
.status-hero .ring.purple {background:oklch(0.94 0.04 305); color:oklch(0.42 0.14 295)}
.status-hero .ring.danger{background:var(--danger-tint); color:oklch(0.50 0.13 20)}
.status-hero .ring.muted{background:var(--neutral-tint); color:var(--ink-3)}
.status-hero .status-label.muted{color:var(--ink-3)}
.status-hero .ring::after{
  content:""; position:absolute; inset:-8px; border-radius:50%;
  border:2px solid currentColor; opacity:.22;
  animation: rfidPulse 2.4s ease-out infinite;
}
.status-hero .status-label{
  font-size:22px; font-weight:800; letter-spacing:-0.01em; margin:0;
}
.status-hero .time{font-size:14px; color:var(--ink-3); margin-top:4px}
.tap-rows{
  display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:18px;
}
.tap-row{
  padding:10px 12px; border-radius:12px; background:var(--surface-2);
  text-align:left;
}
.tap-row b{font-size:13px; display:block}
.tap-row span{font-size:11px; color:var(--ink-3)}

.week-row{
  display:grid; grid-template-columns:repeat(7,1fr); gap:8px;
}
.week-box{
  background:var(--surface); border:1px solid var(--border);
  border-radius:12px; padding:10px 6px; text-align:center;
}
.week-box .day{font-size:11px; color:var(--ink-3); font-weight:600}
.week-box .date{font-size:18px; font-weight:700; margin:4px 0 6px; font-family:"JetBrains Mono",monospace}
.week-box .ico{
  width:24px; height:24px; border-radius:50%;
  display:grid; place-items:center; margin:0 auto;
  font-size:12px; font-weight:700;
}
.week-box.hadir .ico{background:var(--success-tint); color:var(--success-ink)}
.week-box.late  .ico{background:var(--warning-tint); color:var(--warning-ink)}
.week-box.sakit .ico{background:oklch(0.94 0.04 235); color:oklch(0.42 0.14 240)}
.week-box.izin  .ico{background:oklch(0.94 0.04 305); color:oklch(0.42 0.14 295)}
.week-box.alpha .ico{background:var(--danger-tint); color:oklch(0.50 0.13 20)}
.week-box.libur .ico{background:var(--neutral-tint); color:var(--ink-4)}

.month-grid{
  display:grid; grid-template-columns:repeat(7,1fr); gap:5px;
}
.month-cell{
  aspect-ratio:1/1; border-radius:9px;
  display:flex; align-items:center; justify-content:center;
  font-size:12px; font-weight:600;
  background:var(--surface-2); color:var(--ink-2);
  position:relative;
  font-family:"JetBrains Mono",monospace;
}
.month-cell.empty{background:transparent}
.month-cell.hadir{background:var(--success-tint); color:var(--success-ink)}
.month-cell.late{background:var(--warning-tint); color:var(--warning-ink)}
.month-cell.sakit{background:oklch(0.94 0.04 235); color:oklch(0.42 0.14 240)}
.month-cell.izin {background:oklch(0.94 0.04 305); color:oklch(0.42 0.14 295)}
.month-cell.alpha{background:var(--danger-tint); color:oklch(0.45 0.13 20)}
.month-cell.libur{background:var(--neutral-tint); color:var(--ink-4)}
.month-cell.today{box-shadow:0 0 0 2px var(--primary)}
.month-cell .dot{
  position:absolute; bottom:3px; left:50%; transform:translateX(-50%);
  width:4px; height:4px; border-radius:50%;
}
.month-head{
  display:grid; grid-template-columns:repeat(7,1fr); gap:5px; margin-bottom:6px;
  font-size:11px; font-weight:700; color:var(--ink-3); text-align:center;
}

/* ---------- Device card ---------- */
.device-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(280px, 1fr)); gap:16px;
}
.device-card{
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius-lg); padding:18px;
  position:relative; overflow:hidden;
}
.device-card .head{display:flex; align-items:flex-start; gap:12px}
.device-card .icon-box{
  width:42px; height:42px; border-radius:11px;
  background:var(--primary-tint); color:var(--primary-hover);
  display:grid; place-items:center;
}
.device-card .meta b{font-size:15px; font-weight:700; letter-spacing:-0.01em}
.device-card .meta span{font-size:12px; color:var(--ink-3); display:block; font-family:"JetBrains Mono",monospace}
.signal-bar{
  display:flex; gap:3px; align-items:flex-end; height:14px;
}
.signal-bar i{width:3px; background:var(--border); border-radius:1px}
.signal-bar i.on{background:var(--success)}
.signal-bar i:nth-child(1){height:30%}
.signal-bar i:nth-child(2){height:55%}
.signal-bar i:nth-child(3){height:78%}
.signal-bar i:nth-child(4){height:100%}

.log-list{margin-top:14px; border-top:1px solid var(--border-2); padding-top:12px}
.log-list .log-item{
  display:flex; align-items:center; gap:8px;
  padding:6px 0; font-size:12.5px;
}
.log-list .log-item .who{flex:1; color:var(--ink-2); font-weight:500}
.log-list .log-item .when{color:var(--ink-4); font-family:"JetBrains Mono",monospace; font-size:11.5px}

/* ---------- Reports ---------- */
.chart-row{display:grid; grid-template-columns: 1.4fr 1fr; gap:16px}
.line-chart{height:200px; position:relative; padding:8px 0 4px}
.line-chart svg{width:100%; height:100%}

.pie-wrap{display:flex; align-items:center; gap:18px; padding:12px 4px}
.pie-svg{width:140px; height:140px; flex-shrink:0}
.pie-legend{flex:1; display:flex; flex-direction:column; gap:8px}
.pie-legend .row{display:flex; align-items:center; gap:10px; font-size:13px}
.pie-legend .row .sw{width:10px; height:10px; border-radius:3px}
.pie-legend .row b{font-weight:600; margin-left:auto; font-family:"JetBrains Mono",monospace}

/* ---------- Filter bar ---------- */
.filter-bar{
  display:flex; gap:10px; flex-wrap:wrap;
  padding:14px; background:var(--surface);
  border:1px solid var(--border); border-radius:var(--radius-lg);
  align-items:center;
}
.filter-bar .sep{width:1px; height:24px; background:var(--border-2)}

/* ---------- Preset pills ---------- */
.preset-row{display:flex; gap:8px; flex-wrap:wrap}
.preset{
  padding:8px 14px; border-radius:999px;
  background:var(--surface); border:1px solid var(--border);
  font-size:12.5px; font-weight:600; color:var(--ink-2);
  transition: all .15s;
}
.preset:hover{border-color:var(--primary-ring); color:var(--primary-hover)}
.preset.active{background:var(--primary-tint); border-color:var(--primary-ring); color:var(--primary-hover)}

/* ---------- Day schedule card ---------- */
.day-grid{display:grid; grid-template-columns:repeat(2,1fr); gap:14px}
.day-card{
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius-lg); padding:18px;
  position:relative; overflow:hidden;
  transition: opacity .25s, border-color .2s;
}
.day-card.off{opacity:.55}
.day-card .head{display:flex; align-items:center; gap:10px; margin-bottom:14px}
.day-card .head b{font-size:15px; font-weight:700; letter-spacing:-0.01em; flex:1}
.day-card .time-row{display:grid; grid-template-columns:repeat(3,1fr); gap:8px}
.time-pill{
  display:flex; align-items:center; gap:6px;
  padding:8px 10px; background:var(--surface-2);
  border:1px solid var(--border-2); border-radius:10px;
  font-family:"JetBrains Mono", monospace; font-size:13px; font-weight:600;
}
.time-pill svg{flex-shrink:0; opacity:.7}
.time-pill input{
  border:none; outline:none; background:none;
  width:100%; font-family:inherit; font-size:13px; font-weight:600; color:var(--ink);
}

/* ---------- Scrollbar ---------- */
.content::-webkit-scrollbar, .modal::-webkit-scrollbar{width:8px; height:8px}
.content::-webkit-scrollbar-thumb, .modal::-webkit-scrollbar-thumb{background:var(--border); border-radius:4px}
.content::-webkit-scrollbar-thumb:hover, .modal::-webkit-scrollbar-thumb:hover{background:var(--ink-4)}

/* ---------- Toast / inline alert ---------- */
.toast{
  position:fixed; bottom:80px; right:20px;
  background:var(--ink); color:white;
  padding:12px 16px; border-radius:12px;
  font-size:13px; font-weight:500;
  box-shadow:var(--shadow-3);
  z-index:40;
  animation: toastIn .35s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes toastIn{from{opacity:0; transform:translateY(8px)} to{opacity:1; transform:none}}

/* small */
@media (max-width: 1100px){
  .metric-row{grid-template-columns:repeat(2,1fr)}
  .chart-row{grid-template-columns:1fr}
  .day-grid{grid-template-columns:1fr}
}
@media (max-width: 760px){
  .app{grid-template-columns:1fr}
  .sidebar{display:none}
  .search{width:auto; flex:1}
}

/* ============================================================
   Extended animations + soft box pattern decoration
   ============================================================ */

/* --- Card sheen on hover --- */
.card, .metric, .day-card, .device-card, .feat, .portal-card, .parent-card, .status-hero, .profile, .big-num, .arch-node, .flow-step, .benefit, .prob-row, .status-card{
  position:relative;
}
.card::before, .metric::before, .day-card::before, .device-card::before{
  content:""; position:absolute; inset:0;
  border-radius:inherit;
  background:linear-gradient(120deg, transparent 30%, rgba(255,255,255,.45) 50%, transparent 70%);
  transform:translateX(-130%);
  pointer-events:none; opacity:0;
  transition: transform 1.1s cubic-bezier(.2,.7,.2,1), opacity .25s;
  z-index:1;
}
.card:hover::before, .metric:hover::before, .day-card:hover::before, .device-card:hover::before{
  transform:translateX(130%); opacity:1;
}
.card > *, .metric > *, .day-card > *, .device-card > *{position:relative; z-index:2}
/* Card-head must sit above its sibling .table-wrap so dropdowns anchored
   inside the head (Export, kelas filter) can float over the table. */
.card > .card-head{z-index:5}

/* --- Subtle box-pattern accent on cards --- */
.card, .metric, .day-card, .device-card{
  background-image:
    radial-gradient(circle at 1px 1px, var(--grid-dot) 1px, transparent 0);
  background-size: 24px 24px;
  background-position: 12px 12px;
  background-blend-mode: multiply;
}
.metric, .card, .day-card, .device-card{
  background-color:var(--surface);
}

/* --- Floating metric icons --- */
.metric-icon{
  animation: iconFloat 4.5s ease-in-out infinite;
}
.metric:nth-child(2) .metric-icon{animation-delay:-.8s}
.metric:nth-child(3) .metric-icon{animation-delay:-1.6s}
.metric:nth-child(4) .metric-icon{animation-delay:-2.4s}
@keyframes iconFloat{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(-3px)}
}

/* --- Soft monochrome live-dot recolor --- */
.nav-item .badge-dot{
  box-shadow:0 0 0 3px oklch(0.62 0.07 150 / .18);
  animation: dotBlink 2.2s ease-in-out infinite;
}
@keyframes dotBlink{
  0%,100%{opacity:1}
  50%{opacity:.45}
}
.device-pill .live{
  box-shadow:0 0 0 0 oklch(0.62 0.07 150 / .55);
  animation: liveDot 1.8s ease-out infinite;
}

/* --- Tab underline slide --- */
.tab.active, .tabbar button.active{
  position:relative;
}
.tab.active::after{
  content:""; position:absolute; left:14px; right:14px; bottom:4px;
  height:2px; border-radius:2px; background:var(--primary);
  animation: tabSlide .35s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes tabSlide{from{transform:scaleX(0)} to{transform:scaleX(1)}}

/* --- Smooth fade-up for filter bar, page-fade children stagger --- */
.filter-bar{animation: fadeUp .5s cubic-bezier(.2,.7,.2,1) both}
.preset{animation: fadeUp .45s cubic-bezier(.2,.7,.2,1) both}
.preset:nth-child(1){animation-delay:.05s}
.preset:nth-child(2){animation-delay:.12s}
.preset:nth-child(3){animation-delay:.19s}
@keyframes fadeUp{
  from{opacity:0; transform:translateY(6px)}
  to{opacity:1; transform:none}
}

/* --- Day card stagger entrance --- */
.day-card{animation: fadeUp .5s cubic-bezier(.2,.7,.2,1) both}
.day-card:nth-child(1){animation-delay:.05s}
.day-card:nth-child(2){animation-delay:.12s}
.day-card:nth-child(3){animation-delay:.19s}
.day-card:nth-child(4){animation-delay:.26s}
.day-card:nth-child(5){animation-delay:.33s}
.day-card:nth-child(6){animation-delay:.40s}
.day-card:hover{transform:translateY(-2px); box-shadow:var(--shadow-2); border-color:var(--ink-4)}
.day-card{transition: transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s, border-color .2s, opacity .25s}

/* --- Device card hover lift + soft glow --- */
.device-card{
  transition: transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .3s, border-color .2s;
  animation: fadeUp .55s cubic-bezier(.2,.7,.2,1) both;
}
.device-card:hover{
  transform:translateY(-2px);
  box-shadow:var(--shadow-2);
  border-color:var(--ink-4);
}

/* --- Section card subtle hover lift --- */
.card{transition: box-shadow .3s, border-color .2s}
.card:hover{box-shadow:var(--shadow-2)}

/* --- Topbar subtle scroll-driven shadow --- */
.topbar{
  transition: box-shadow .3s, background .3s;
}
.content:hover ~ .topbar, .content:focus-within ~ .topbar{box-shadow: var(--shadow-1)}

/* --- Brand mark micro-rotation on hover --- */
.brand:hover .brand-mark{animation: brandSpin 1.2s cubic-bezier(.2,.7,.2,1)}
@keyframes brandSpin{
  0%{transform:rotate(0deg) scale(1)}
  40%{transform:rotate(-6deg) scale(1.05)}
  100%{transform:rotate(0deg) scale(1)}
}

/* --- Avatar hover ring --- */
.avatar{transition: transform .25s, box-shadow .25s}
.student-cell:hover .avatar{transform:scale(1.06); box-shadow: 0 0 0 4px var(--neutral-tint)}

/* --- Soft glow halo behind brand-mark --- */
.brand-mark::before{
  content:""; position:absolute; inset:-6px; border-radius:18px;
  border:1px solid var(--primary-ring); opacity:0;
  animation: haloPulse 3.2s ease-out infinite;
  z-index:-1;
}
@keyframes haloPulse{
  0%{opacity:.5; transform:scale(.92)}
  70%{opacity:0; transform:scale(1.25)}
  100%{opacity:0; transform:scale(1.25)}
}

/* --- Subtle marquee shimmer on table header --- */
table.data thead tr{
  position:sticky; top:0; z-index:1;
}
table.data thead::after{
  content:"";
}

/* --- Filter bar / search focus ring stronger --- */
.search:focus-within{
  border-color:var(--ink-4);
  box-shadow:0 0 0 4px var(--neutral-tint);
}

/* --- Page transition: subtle scale --- */
.page-fade{animation: pageIn .55s cubic-bezier(.2,.7,.2,1) both}
@keyframes pageIn{
  from{opacity:0; transform:translateY(10px) scale(.995)}
  to{opacity:1; transform:none}
}

/* --- Modal close icon spin --- */
.modal-head .icon-btn:hover{
  transform: rotate(90deg);
  transition: transform .35s cubic-bezier(.2,.7,.2,1);
}

/* --- Soft inner-glow ring on portal-card top accent --- */
.portal-card::before{
  background: linear-gradient(90deg, var(--ink-4), var(--ink), var(--ink-4));
}

/* --- Status hero ring glow (mono softening) --- */
.status-hero .ring{
  animation: ringSoftPulse 3s ease-in-out infinite;
}
@keyframes ringSoftPulse{
  0%,100%{transform:scale(1)}
  50%{transform:scale(1.04)}
}

/* --- Week box hover --- */
.week-box{transition: transform .2s, box-shadow .25s, border-color .2s; cursor:pointer}
.week-box:hover{transform:translateY(-2px); border-color:var(--ink-4); box-shadow:var(--shadow-1)}

/* --- Month cell hover --- */
.month-cell:not(.empty){transition: transform .15s, box-shadow .2s}
.month-cell:not(.empty):hover{transform:scale(1.08); box-shadow:var(--shadow-1); z-index:2}

/* --- Soft pop for status badges on appear --- */
.badge{animation: badgePop .45s cubic-bezier(.4,1.4,.5,1) both}
@keyframes badgePop{
  from{opacity:0; transform:scale(.85)}
  to{opacity:1; transform:scale(1)}
}

/* --- Subtle parallax-like grid that floats on parent-wrap --- */
.parent-wrap{
  animation: gridDrift 24s linear infinite;
}
@keyframes gridDrift{
  from{background-position: -1px -1px, -1px -1px, 0 0, 0 0, 0 0}
  to  {background-position: 31px 31px, 31px 31px, 0 0, 0 0, 0 0}
}


/* =========================================================================
   Custom dropdown components — used by reports + students filter bars.
   Replaces plain <select> dengan Alpine-driven panel yang punya badge
   per opsi + colored dot indicator + animated chevron.
   ========================================================================= */

/* ---- Shared trigger/menu chrome ---- */
.status-chevron {
  color: var(--ink-3);
  font-size: 10px;
  transition: transform .2s;
}
.status-chevron.is-open { transform: rotate(180deg); }

.status-check {
  color: var(--success-ink);
  font-weight: 700;
  font-family: "JetBrains Mono", monospace;
  font-size: 13px;
}

/* ---- Kelas dropdown (used in reports + students) ---- */
.kelas-select { position: relative; }

.kelas-trigger {
  height: 36px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  transition: border-color .15s, box-shadow .15s;
}
.kelas-trigger:hover { border-color: var(--primary-ring); }
.kelas-trigger:focus-visible {
  outline: none;
  border-color: var(--primary-ring);
  box-shadow: 0 0 0 3px var(--primary-tint);
}
.kelas-trigger > .ico { color: var(--ink-3); }

.kelas-trigger-label {
  min-width: 80px;
  white-space: nowrap;
}

.kelas-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 220px;
  z-index: 30;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: 12px;
  box-shadow: var(--shadow-3);
  padding: 6px;
  max-height: 320px;
  overflow-y: auto;
  transition: opacity .18s, transform .18s;
}

.kelas-option {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: none;
  border: none;
  border-radius: 8px;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: background .12s;
}
.kelas-option:hover      { background: var(--surface-2); }
.kelas-option.is-active  { background: var(--primary-tint); font-weight: 600; }
.kelas-option-label      { flex: 1; }

.kelas-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  height: 22px;
  padding: 0 8px;
  background: var(--primary-tint);
  color: var(--primary-hover);
  border: 1px solid var(--primary-ring);
  border-radius: 6px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}
.kelas-badge.muted {
  background: var(--neutral-tint);
  color: var(--ink-3);
  border-color: var(--border);
}

@media (max-width: 600px) {
  .kelas-select  { width: 100%; }
  .kelas-trigger { width: 100%; }
}

/* ============================================================
   Export multi-format dropdown (Laporan page)
   ============================================================ */
.export-select { position: relative; }

.export-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 320px;
  z-index: 30;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: 12px;
  box-shadow: var(--shadow-3);
  padding: 8px;
  max-height: 460px;
  overflow-y: auto;
  transition: opacity .18s, transform .18s;
}

.export-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-4);
  padding: 8px 10px 6px;
}
.export-group-label:not(:first-child) {
  margin-top: 4px;
  border-top: 1px solid var(--border);
}

.export-option {
  width: 100%;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: background .12s;
}
.export-option:hover { background: var(--surface-2); }
.export-option:focus-visible {
  outline: none;
  background: var(--primary-tint);
}

.export-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--primary-tint);
  color: var(--primary);
  flex-shrink: 0;
}

.export-option-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.export-option-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.export-option-sub {
  font-size: 11px;
  color: var(--ink-3);
  line-height: 1.4;
}

@media (max-width: 600px) {
  .export-select { width: 100%; }
  .export-menu   { left: 0; right: auto; min-width: 100%; }
}

/* ============================================================
   Tab bar — used on /admin/students (Aktif | Arsip)
   ============================================================ */
.tab-bar {
  display: flex;
  gap: 4px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
  padding: 0 2px;
}

.tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  margin-bottom: -1px;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-3);
  text-decoration: none;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.tab:hover { color: var(--ink); background: var(--surface-2); }
.tab.is-active {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--border);
  border-bottom-color: var(--surface);
}
.tab > .ico { color: inherit; }

.tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 20px;
  padding: 0 7px;
  background: var(--primary-tint);
  color: var(--primary-hover);
  border-radius: 999px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  font-weight: 700;
}
.tab-badge.muted {
  background: var(--neutral-tint);
  color: var(--ink-3);
}
