:root{
  --bg:#f4f6fa;--surface:#fff;--surface2:#f8fafc;--line:#e4e8ef;--text:#0f172a;--muted:#64748b;
  --accent:#2563eb;--accent-soft:#e8f0ff;--ok:#16a34a;--ok-soft:#e7f7ed;--warn:#d97706;--warn-soft:#fff4e0;
  --bad:#dc2626;--bad-soft:#fdeaea;--shadow:0 1px 2px rgba(15,23,42,.06),0 4px 14px rgba(15,23,42,.05);
  --side:#0f172a;--side-text:#cbd5e1;--side-active:#1e293b;--side-on:var(--accent);--side-on-text:#fff;--side-line:rgba(255,255,255,.08);--on-accent:#fff;--radius:12px;
}
[data-theme=dark]{
  --bg:#0a0a0a;--surface:#171717;--surface2:#1e1e1e;--line:#ffffff1a;--text:#fafafa;--muted:#a1a1a1;
  --accent:#fafafa;--accent-soft:#262626;--on-accent:#0a0a0a;--ok:#00bb7f;--ok-soft:#00bb7f1f;--warn:#f99c00;--warn-soft:#f99c001f;
  --bad:#ff6568;--bad-soft:#ff65681f;--shadow:0 1px 2px rgba(0,0,0,.4),0 6px 18px rgba(0,0,0,.25);
  --side:#171717;--side-text:#fafafa;--side-active:#262626;--side-on:#262626;--side-on-text:#fafafa;--side-line:#ffffff1a;
}
*{box-sizing:border-box}html,body{margin:0;height:100%}
body{font:14px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Inter,sans-serif;background:var(--bg);color:var(--text)}
svg.i{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:none}
.app{display:flex;min-height:100vh}
.side{width:244px;background:var(--side);color:var(--side-text);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;flex:none;overflow:hidden;transition:width .28s cubic-bezier(.77,0,.175,1)}
[data-theme=dark] .side{border-right:1px solid var(--side-line)}
.brand{display:flex;gap:12px;align-items:center;padding:20px 18px 16px}
.logo{width:38px;height:38px;border-radius:10px;flex:none;display:block}
.brand b{display:block;color:var(--side-on-text);font-size:15px}.brand span{font-size:11px;opacity:.7;display:block;max-width:168px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nav{padding:8px 10px;flex:1;overflow-y:auto;overflow-x:hidden}
.nav h6{margin:14px 10px 6px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;opacity:.5;font-weight:600}
.nav a{display:flex;gap:12px;align-items:center;padding:9px 12px;border-radius:9px;color:var(--side-text);text-decoration:none;cursor:pointer;margin:2px 0}
.nav a:hover{background:var(--side-active);color:var(--side-on-text)}
.nav a.on{background:var(--side-on);color:var(--side-on-text)}[data-theme=light] .nav a.on{box-shadow:0 4px 12px rgba(37,99,235,.35)}
.nav a .run{margin-left:auto;font-size:10px;font-weight:650;color:#fbbf24;background:rgba(245,158,11,.16);border-radius:99px;padding:2px 6px;white-space:nowrap}
.nav a.on .run{color:#fff;background:rgba(255,255,255,.22)}
.nav .dot{margin-left:auto;width:8px;height:8px;border-radius:50%;background:var(--warn)}
.sidefoot{padding:14px 18px;border-top:1px solid var(--side-line);font-size:12px;display:flex;justify-content:space-between;align-items:center}
.icon-btn{background:none;border:0;color:inherit;cursor:pointer;padding:6px;border-radius:8px;display:grid;place-items:center}
.icon-btn:hover{background:rgba(127,127,127,.15)}
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.top{height:60px;background:var(--surface);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:12px;padding:0 24px;position:sticky;top:0;z-index:5}
.top h1{font-size:17px;margin:0;font-weight:650}
.spacer{flex:1}
.hamb{display:grid}
.hamb svg.ham-m{display:none}
.user{display:flex;align-items:center;gap:9px;padding:4px 10px 4px 4px;border-radius:99px;border:1px solid var(--line)}
.avatar{width:28px;height:28px;border-radius:50%;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-weight:700;font-size:12px}
.view{padding:24px;max-width:1180px;width:100%;margin:0 auto;padding-bottom:90px}
.pagehead{display:flex;align-items:flex-end;gap:16px;margin-bottom:20px;flex-wrap:wrap}
.pagehead h2{margin:0;font-size:22px;letter-spacing:-.01em}.pagehead p{margin:3px 0 0;color:var(--muted)}
.banner{display:flex;gap:12px;align-items:center;padding:12px 16px;border-radius:var(--radius);background:var(--warn-soft);border:1px solid color-mix(in srgb,var(--warn) 35%,transparent);margin-bottom:18px}
.banner svg{color:var(--warn)}.banner .btn{margin-left:auto}
.grid{display:grid;gap:16px}.g4{grid-template-columns:repeat(4,1fr)}.g2{grid-template-columns:repeat(2,1fr)}.g21{grid-template-columns:2fr 1fr}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
.card>.hd{display:flex;align-items:center;gap:10px;padding:16px 20px 0}
.card>.hd h3{margin:0;font-size:14.5px;font-weight:650}.card>.hd small{color:var(--muted);margin-left:auto}
.card>.bd{padding:16px 20px 20px}
.tile{padding:18px 20px;display:flex;flex-direction:column;gap:6px;min-width:0}
.tile .lab{display:flex;gap:8px;align-items:center;color:var(--muted);font-size:12.5px;font-weight:550;text-transform:uppercase;letter-spacing:.04em}
.tile .val{font-size:21px;font-weight:700;letter-spacing:-.02em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile .sub{color:var(--muted);font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile .ic{margin-left:auto;width:34px;height:34px;border-radius:9px;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent)}
.tile.ok .ic{background:var(--ok-soft);color:var(--ok)}.tile.bad .ic{background:var(--bad-soft);color:var(--bad)}.tile.warn .ic{background:var(--warn-soft);color:var(--warn)}
.kv{display:grid;grid-template-columns:150px 1fr;gap:10px 14px}.kv dt{color:var(--muted)}.kv dd{margin:0;font-weight:520;word-break:break-all}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px}
.form{display:grid;gap:18px}
.row{display:grid;grid-template-columns:230px 1fr;gap:16px;align-items:start}
.row>label{font-weight:600;padding-top:8px}.row>label small{display:block;font-weight:400;color:var(--muted);margin-top:2px}
.inp{width:100%;padding:9px 12px;border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--text);font:inherit;outline:none;transition:.15s}
.inp:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
textarea.inp{min-height:110px;font-family:ui-monospace,Menlo,monospace;font-size:12px;resize:vertical}
.inp-group{display:flex;gap:8px}.inp-group .inp{flex:1}
.hint{color:var(--muted);font-size:12.5px;margin-top:5px}
.swrow{display:flex;align-items:center;gap:12px;padding-top:6px}
.range{display:flex;align-items:center;gap:14px}.range input{flex:1;accent-color:var(--accent)}.range b{min-width:46px;text-align:right}
.btn{display:inline-flex;gap:8px;align-items:center;justify-content:center;padding:9px 16px;border-radius:9px;border:1px solid var(--line);background:var(--surface);color:var(--text);font:inherit;font-weight:600;cursor:pointer;transition:.15s;white-space:nowrap}
.btn:hover{background:var(--surface2)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}.btn.primary:hover{filter:brightness(1.08)}
.btn.danger{color:var(--bad);border-color:color-mix(in srgb,var(--bad) 40%,var(--line))}.btn.danger:hover{background:var(--bad-soft)}
.btn.danger.solid{background:var(--bad);border-color:var(--bad);color:#fff}
.btn.sm{padding:6px 12px;font-size:13px}.btn[disabled]{opacity:.55;pointer-events:none}
.badge{display:inline-flex;padding:2px 9px;border-radius:99px;font-size:12px;font-weight:600;background:var(--accent-soft);color:var(--accent)}
.badge.ok{background:var(--ok-soft);color:var(--ok)}.badge.warn{background:var(--warn-soft);color:var(--warn)}.badge.bad{background:var(--bad-soft);color:var(--bad)}
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:18px}
.tabs button{background:none;border:0;border-bottom:2px solid transparent;padding:10px 14px;color:var(--muted);font:inherit;font-weight:600;cursor:pointer;margin-bottom:-1px}
.tabs button.on{color:var(--accent);border-color:var(--accent)}
.sig{display:inline-flex;gap:2px;align-items:flex-end;height:16px;vertical-align:middle}.sig i{width:4px;background:var(--line);border-radius:1px}.sig i.on{background:var(--ok)}
.sig i:nth-child(1){height:5px}.sig i:nth-child(2){height:8px}.sig i:nth-child(3){height:12px}.sig i:nth-child(4){height:16px}
.net{border:1px solid var(--line);border-radius:10px;margin-bottom:8px;overflow:hidden;background:var(--surface)}
.net .l{display:flex;align-items:center;gap:12px;padding:12px 14px;cursor:pointer}.net .l:hover{background:var(--surface2)}
.net .l small{color:var(--muted)}
.net .x{display:none;padding:0 14px 14px 14px;gap:8px;align-items:center}.net.open .x{display:flex}.net.open{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.steps{display:flex;gap:10px;flex-wrap:wrap}
.step{flex:1;min-width:130px;padding:12px 14px;border:1px solid var(--line);border-radius:10px;display:flex;gap:10px;align-items:center;background:var(--surface2)}
.step .s{width:22px;height:22px;border-radius:50%;border:2px solid var(--line);display:grid;place-items:center;font-size:11px;flex:none}
.step small{display:block;color:var(--muted);font-size:11.5px}
.step.run .s{border-color:var(--accent);border-top-color:transparent;animation:spin .8s linear infinite}
.step.ok{border-color:color-mix(in srgb,var(--ok) 50%,var(--line));background:var(--ok-soft)}.step.ok .s{background:var(--ok);border-color:var(--ok);color:#fff}
.step.bad{background:var(--bad-soft)}.step.bad .s{background:var(--bad);border-color:var(--bad);color:#fff}
.step.skip{opacity:.6}
@keyframes spin{to{transform:rotate(360deg)}}
.bar{height:8px;background:var(--line);border-radius:99px;overflow:hidden}.bar i{display:block;height:100%;background:var(--accent);border-radius:99px;transition:width .3s}
.bar.ok i{background:var(--ok)}.bar.warn i{background:var(--warn)}.bar.bad i{background:var(--bad)}
.bar.ind i{width:35%;animation:ind 1.2s ease-in-out infinite}@keyframes ind{0%{margin-left:-35%}100%{margin-left:100%}}
.meter{display:flex;gap:3px;height:34px;align-items:flex-end}.meter i{flex:1;background:var(--line);border-radius:2px;height:30%}
.meter i.hot{background:var(--ok);height:70%}.meter i.peak{background:var(--warn);height:100%}
.drop{border:2px dashed var(--line);border-radius:12px;padding:30px;text-align:center;color:var(--muted);cursor:pointer;transition:.15s}
.drop:hover,.drop.over{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.drop b{display:block;color:var(--text);margin:8px 0 2px}
.list{display:grid}.list .it{display:flex;gap:12px;align-items:center;padding:11px 0;border-bottom:1px solid var(--line)}.list .it:last-child{border:0}
.list .it .t{flex:1;min-width:0}.list .it .t small{display:block;color:var(--muted);overflow:hidden;text-overflow:ellipsis}
.led{width:10px;height:10px;border-radius:50%;background:var(--line);flex:none}.led.on{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}
.console{background:#0a0f1c;color:#c7f9d4;border-radius:10px;padding:14px;font:12px/1.6 ui-monospace,Menlo,monospace;height:460px;overflow:auto;white-space:pre-wrap;word-break:break-all}
.console .t{color:#64748b}.console .e{color:#fca5a5}.console .w{color:#fcd34d}.console .m{color:#93c5fd}
.danger-zone{border-color:color-mix(in srgb,var(--bad) 35%,var(--line))}.danger-zone>.hd h3{color:var(--bad)}
.savebar{position:fixed;left:244px;right:0;bottom:0;background:var(--surface);border-top:1px solid var(--line);box-shadow:0 -6px 20px rgba(15,23,42,.08);padding:12px 24px;display:flex;gap:12px;align-items:center;transform:translateY(110%);transition:.25s;z-index:8}
.savebar.show{transform:none}.savebar .msg{display:flex;gap:9px;align-items:center;font-weight:600}.savebar .msg svg{color:var(--warn)}
.toasts{position:fixed;right:20px;bottom:78px;display:grid;gap:10px;z-index:40}
.toast{background:var(--surface);border:1px solid var(--line);border-left:4px solid var(--ok);box-shadow:var(--shadow);padding:11px 16px;border-radius:10px;min-width:240px;max-width:420px;animation:in .25s}
.toast.bad{border-left-color:var(--bad)}@keyframes in{from{transform:translateX(30px);opacity:0}}
.scrim{display:none}
.modal{position:fixed;inset:0;background:rgba(2,6,23,.55);display:none;place-items:center;z-index:30}.modal.show{display:grid}
.modal .box{background:var(--surface);border-radius:14px;padding:24px;width:min(460px,92vw);box-shadow:0 20px 60px rgba(0,0,0,.35);max-height:92vh;max-height:92dvh;overflow-y:auto;overscroll-behavior:contain}
.modal h3{margin:0 0 6px}.modal p{color:var(--muted);margin:0 0 16px}.modal .acts{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}
.empty{padding:22px 0;text-align:center;color:var(--muted)}
@media(max-width:1100px){.g4{grid-template-columns:repeat(2,1fr)}.g21{grid-template-columns:1fr}}
@media(max-width:900px){
  .side{position:fixed;left:-260px;z-index:25;transition:.25s}.side.open{left:0}
  .scrim.show{display:block;position:fixed;inset:0;background:rgba(2,6,23,.5);z-index:24}
  .savebar{left:0}.g4,.g2,.g21{grid-template-columns:1fr}.row{grid-template-columns:1fr;gap:6px}.row>label{padding-top:0}
  .view{padding:16px;padding-bottom:90px}.top{padding:10px 14px;height:auto;flex-wrap:wrap;row-gap:10px}.top .spacer{display:none}.combo{flex:1 1 0;width:auto;min-width:0}.combo .inp{font-size:16px;height:46px}.combo-ic,.combo-chev{top:14px}.combo-list{max-height:55vh}.user span{display:none}.kv{grid-template-columns:110px 1fr}
  .banner{flex-wrap:wrap}.banner .btn{margin-left:0}.pagehead .btn{flex:1}.tile .tile-acts{flex-direction:column}.tile .tile-acts .btn{width:100%;white-space:normal}.sync-all .btn{width:100%;white-space:normal}.toolbar .btn{white-space:normal}.steps .step{min-width:46%}
}
.view.wide{max-width:1240px}
.toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.toolbar .inp{max-width:320px}
.table-wrap{overflow:auto}
table.people{width:100%;border-collapse:collapse}
table.people th,table.people td{text-align:left;padding:10px 8px;border-bottom:1px solid var(--line);vertical-align:middle}
table.people th{font-size:12px;color:var(--muted);font-weight:650;letter-spacing:.04em;text-transform:uppercase}
table.people tr:hover td{background:var(--surface2)}
table.people .who{display:flex;gap:10px;align-items:center;min-width:180px}
table.people .who b{display:block}
table.people .who small{color:var(--muted)}
.pager{display:flex;gap:8px;align-items:center;justify-content:space-between;margin-top:14px;flex-wrap:wrap}
.sec{margin:8px 2px 10px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:650}
.tile button{margin-top:8px;align-self:flex-start}
.tile .tile-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}.tile .tile-acts button{margin-top:0}
.sync-all{margin-bottom:12px}
select.inp{max-width:320px}
.combo{position:relative;width:min(340px,46vw);flex:none}
.combo .inp{max-width:none;height:42px;padding:0 34px 0 38px;font-weight:650;border:2px solid var(--accent);background:var(--accent-soft);color:var(--text);text-overflow:ellipsis;cursor:pointer}
.combo .inp:focus{background:var(--surface);box-shadow:0 0 0 3px var(--accent-soft)}
.combo-ic,.combo-chev{position:absolute;top:12px;color:var(--accent);pointer-events:none}
.combo-ic{left:11px}.combo-chev{right:10px}
.combo-list{position:absolute;top:calc(100% + 6px);left:0;right:0;max-height:320px;overflow:auto;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);z-index:30;padding:4px}
.combo-list button{display:flex;width:100%;text-align:left;gap:8px;align-items:center;border:0;background:none;color:var(--text);font:inherit;padding:11px 10px;border-radius:8px;cursor:pointer}
.combo-list button small{margin-left:auto;color:var(--muted);font-size:12px}
.combo-list button.cur,.combo-list button:hover{background:var(--accent-soft);color:var(--accent)}
.combo-list button.on{font-weight:650}
.combo-list .empty{padding:12px 8px}
.modal .box.wide{width:min(780px,94vw)}
.gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:12px}
.shot{margin:0;background:var(--surface);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.shot img{width:100%;height:190px;object-fit:cover;background:#0b1120;cursor:zoom-in;display:block}
.shot .miss{height:190px;display:grid;place-items:center;color:var(--muted);background:var(--surface2)}
.shot figcaption{padding:8px 10px;font-size:12px;color:var(--muted)}
.shot figcaption b{display:block;color:var(--text);font-size:12.5px;font-weight:650}
.punch img{width:52px;height:68px;object-fit:cover;border-radius:8px;cursor:zoom-in;display:block;background:#0b1120}
.punch .miss{width:52px;height:68px;display:grid;place-items:center;text-align:center;font-size:11px;line-height:1.2;color:var(--muted);background:var(--surface2);border-radius:8px;padding:4px}
.list .it.on{background:var(--surface2);margin:0 -8px;padding-left:8px;padding-right:8px;border-radius:10px}
.device-pick{display:flex;flex-direction:column;gap:8px;max-height:360px;overflow:auto}
.device-pick label{display:flex;gap:10px;align-items:center;padding:8px 10px;border:1px solid var(--line);border-radius:10px}
table.people tbody tr{cursor:pointer}
table.people.flat tbody tr{cursor:default}
table.people.flat.click tbody tr[data-sid]{cursor:pointer}
table.people.flat.click tbody tr[data-sid]:hover td{background:var(--surface2)}
table.people.flat tbody tr:hover td{background:transparent}
.lightbox{width:min(920px,94vw);background:#000;padding:8px;border-radius:14px}
.lightbox img{width:100%;max-height:78vh;object-fit:contain;display:block}
.lightbox p{color:#e5ebf5;margin:8px 8px 4px}

input[type=checkbox]{width:19px;height:19px;flex:none;accent-color:var(--accent);cursor:pointer;margin:0}
.tico{display:inline-flex;vertical-align:middle;color:var(--accent)}
.tico svg.i{width:20px;height:20px}
@media(max-width:700px){
  input[type=checkbox]{width:22px;height:22px}
  .btn.sm{min-height:40px}
  .toolbar .inp,select.inp{max-width:none;flex:1 1 100%;font-size:16px;height:44px}
  #devNote{margin:0!important}
  #devTiles{grid-template-columns:repeat(2,1fr)!important;gap:10px}
  #devTiles .tile .sub{display:none}
  table.devtbl thead{display:none}
  table.devtbl,table.devtbl tbody,table.devtbl tr,table.devtbl td{display:block;width:100%}
  table.devtbl tr{position:relative;padding:12px 12px 12px 54px;margin-bottom:10px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
  table.devtbl td{border:0;padding:3px 0;text-align:left}
  table.devtbl tr:hover td{background:transparent}
  table.devtbl td.c-sel{position:absolute;left:14px;top:14px;width:auto;padding:0}
  table.devtbl td[data-label]::before{content:attr(data-label) ": ";color:var(--muted);font-size:12px}
  table.devtbl td[data-label] .hint{display:inline}
  table.devtbl td:empty{display:none}
  table.devtbl td.c-act{display:flex;gap:8px;margin-top:8px;padding-top:10px;border-top:1px solid var(--line)}
  table.devtbl td.c-act .btn{flex:1}
  table.devtbl td.empty{padding:16px 0}
}

table.devtbl tbody tr[data-id]{cursor:pointer}
.modal .box.xl{width:min(1000px,96vw);max-height:92vh;overflow:auto}
.phead{display:flex;gap:12px;align-items:flex-start}
.phead .badge{margin-left:6px}
.psum{padding:12px 14px;border-radius:12px;background:var(--ok-soft)}
.psum.warn{background:var(--warn-soft)}
.psum ul{margin:6px 0 4px 18px;padding:0}
.pgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin-top:12px}
.pblock{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--surface)}
.pblock h4{display:flex;align-items:center;gap:8px;margin:0 0 6px;font-size:14px}
.pblock h4 svg.i{color:var(--accent)}
.prow{display:flex;justify-content:space-between;gap:12px;padding:6px 0;border-bottom:1px dashed var(--line)}
.prow:last-child{border-bottom:0}
.prow .pl{color:var(--muted);flex:0 0 46%}
.prow .pv{text-align:right;font-weight:560;word-break:break-word;display:flex;flex-wrap:wrap;gap:4px 8px;justify-content:flex-end;align-items:center}
.muted{color:var(--muted)}
@media(max-width:700px){
  .pgrid{grid-template-columns:1fr}
  .modal .box.xl{padding:16px}
  .prow{flex-direction:column;gap:2px}
  .prow .pl{flex:none}
  .prow .pv{text-align:left;justify-content:flex-start}
  .modal .acts .btn{flex:1;min-height:44px}
}

/* ---- Animation ---- */
:root{--ease:cubic-bezier(.22,.61,.36,1);--spring:cubic-bezier(.34,1.4,.64,1)}
@keyframes fade-up{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
@keyframes pop-in{from{opacity:0;transform:translateY(8px) scale(.96)}to{opacity:1;transform:none}}
@keyframes drop-in{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateX(30px)}}
@keyframes pulse-ring{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 45%,transparent)}100%{box-shadow:0 0 0 8px transparent}}
@keyframes shimmer{to{background-position:-200% 0}}

.view.enter{animation:fade-up .35s var(--ease)}
.card,.tile,.btn,.badge,.net,.step,.shot,.pblock,.drop,.toast,.nav a,.tabs button,.icon-btn,.combo-list button,table.people td,.list .it{transition:background-color .18s var(--ease),border-color .18s var(--ease),box-shadow .2s var(--ease),transform .2s var(--ease),color .18s var(--ease),opacity .18s var(--ease),filter .18s var(--ease)}
.card.tile:hover,.tile.card:hover,.shot:hover{transform:translateY(-2px);box-shadow:0 2px 4px rgba(15,23,42,.08),0 10px 24px rgba(15,23,42,.10)}
.btn:active{transform:scale(.97)}
.btn.primary:hover{box-shadow:0 4px 12px color-mix(in srgb,var(--accent) 40%,transparent)}
.nav a{position:relative}.nav a:hover{transform:translateX(3px)}.nav a.on{transform:none}
.nav a svg.i{transition:transform .2s var(--spring)}.nav a:hover svg.i{transform:scale(1.12)}
.icon-btn:active{transform:scale(.9)}
#themeBtn svg{transition:transform .4s var(--spring)}#themeBtn:hover svg{transform:rotate(25deg)}
.tabs button{transition:color .18s var(--ease),border-color .18s var(--ease)}
.shot img{transition:transform .35s var(--ease)}.shot:hover img{transform:scale(1.04)}.shot{overflow:hidden}
.punch img{transition:transform .2s var(--ease)}.punch img:hover{transform:scale(1.08)}
.led.on{animation:pulse-ring 1.8s ease-out infinite}
.bar i{transition:width .5s var(--ease)}
.net .x{animation:fade-in .2s var(--ease)}.net.open .x{animation:fade-up .25s var(--ease)}
.pblock{animation:fade-up .3s var(--ease) backwards}.pgrid .pblock:nth-child(2){animation-delay:.04s}.pgrid .pblock:nth-child(3){animation-delay:.08s}.pgrid .pblock:nth-child(4){animation-delay:.12s}.pgrid .pblock:nth-child(n+5){animation-delay:.16s}

/* modal */
.modal.show{animation:fade-in .2s var(--ease)}
.modal.show .box{animation:pop-in .26s var(--spring)}
.scrim.show{animation:fade-in .2s var(--ease)}
.combo-list:not([hidden]){animation:drop-in .16s var(--ease);transform-origin:top}
.combo-chev{transition:transform .2s var(--ease)}.combo .inp[aria-expanded=true]~.combo-chev,.combo:focus-within .combo-chev{transform:rotate(180deg)}

/* toast leaving */
.toast{animation:in .3s var(--spring)}.toast.out{animation:toast-out .25s var(--ease) forwards}


/* sidebar drawer on mobile */
@media(max-width:900px){.side{transition:left .28s var(--ease)}}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  .led.on{animation:none}
}

.loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:22px 0;color:var(--muted)}
.loading .spin{width:16px;height:16px;border-radius:50%;border:2px solid var(--accent);border-top-color:transparent;animation:spin .8s linear infinite;flex:none}

/* ---- Giám sát dịch vụ ---- */
.tdot{width:10px;height:10px;border-radius:50%;background:var(--muted);flex:none;display:inline-block}
.tdot.ok{background:var(--ok);animation:pulse-ring 1.8s ease-out infinite}.tdot.warn{background:var(--warn)}.tdot.bad{background:var(--bad)}.tdot.off{background:var(--muted);opacity:.55}
.topo{position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 clamp(28px,6vw,84px);align-items:stretch;padding:4px 2px}
.topo-links{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.tcol{display:flex;flex-direction:column;gap:10px;position:relative;z-index:1}
.tcol.mid{justify-content:center}
.tcol h5{margin:0 0 2px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:650}
.tcol.mid h5{position:absolute;top:0;left:0}
.tnode{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:11px;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow);min-width:0;transition:border-color .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease)}
.tnode .tic{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);flex:none}
.tnode.ok .tic{background:var(--ok-soft);color:var(--ok)}.tnode.warn .tic{background:var(--warn-soft);color:var(--warn)}.tnode.bad .tic{background:var(--bad-soft);color:var(--bad)}.tnode.off .tic{background:var(--surface2);color:var(--muted)}
.tnode .tt{min-width:0;flex:1}.tnode b{display:block;font-size:13px;font-weight:650;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tnode small{display:block;color:var(--muted);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tnode.bad{border-color:color-mix(in srgb,var(--bad) 45%,var(--line))}.tnode.warn{border-color:color-mix(in srgb,var(--warn) 45%,var(--line))}
.tnode.click{cursor:pointer}.tnode.click:hover,.tnode.click:focus-visible{border-color:var(--accent);transform:translateY(-1px);outline:none}
.lk{fill:none;stroke-width:1.8;stroke:var(--line);stroke-linecap:round}
.lk.ok{stroke:var(--ok);stroke-dasharray:5 6;animation:flow 1.1s linear infinite;opacity:.85}
.lk.warn{stroke:var(--warn);stroke-dasharray:5 6;animation:flow 1.6s linear infinite}
.lk.bad{stroke:var(--bad);stroke-dasharray:2 6;opacity:.8}
.lk.off{stroke:var(--muted);stroke-dasharray:2 6;opacity:.35}
@keyframes flow{to{stroke-dashoffset:-22}}
.topo-legend{display:flex;gap:18px;flex-wrap:wrap;margin-top:16px;padding-top:12px;border-top:1px solid var(--line);color:var(--muted);font-size:12.5px}
.topo-legend span{display:inline-flex;gap:7px;align-items:center}.topo-legend .tdot{animation:none}
.svc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,460px),1fr));gap:16px;align-items:start}
.card.svc{padding:18px 20px;border-top:3px solid var(--line);scroll-margin-top:84px}
.card.svc.ok{border-top-color:var(--ok)}.card.svc.warn{border-top-color:var(--warn)}.card.svc.bad{border-top-color:var(--bad)}.card.svc.off{border-top-color:var(--muted)}
.card.svc.flash{animation:svc-flash 1.2s var(--ease)}
@keyframes svc-flash{0%,60%{box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 55%,transparent),var(--shadow)}100%{box-shadow:var(--shadow)}}
.svc-hd{display:flex;gap:12px;align-items:flex-start}.svc-hd .tdot{margin-top:6px}
.svc-t{flex:1;min-width:0}.svc-t h3{margin:0;font-size:15px;font-weight:650}.svc-t .hint{margin-top:3px;display:block}
.svc-state{display:flex;gap:10px;align-items:center;margin:14px 0 4px;flex-wrap:wrap}.svc-state>span:last-child{color:var(--text);flex:1;min-width:0}
.badge.off{background:var(--surface2);color:var(--muted);border:1px solid var(--line)}
.svc-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:8px;margin-top:12px}
.svc-metrics>div{background:var(--surface2);border:1px solid var(--line);border-radius:9px;padding:8px 11px;min-width:0}
.svc-metrics small{display:block;color:var(--muted);font-size:11.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.svc-metrics b{display:block;font-size:14px;font-weight:650;margin-top:1px;overflow-wrap:anywhere}
.svc-sub{margin:16px 0 6px;font-size:13px}.svc-sub.bad{color:var(--bad)}
.svc-det{margin-top:12px}.svc-det summary{cursor:pointer;font-weight:600;display:flex;gap:8px;align-items:center}
.svc-det summary span{background:var(--surface2);border:1px solid var(--line);border-radius:99px;padding:0 8px;font-size:12px;color:var(--muted);font-weight:600}
.svc-det summary.bad,.svc-det summary.bad span{color:var(--bad)}
.svc-foot{margin-top:14px;padding-top:10px;border-top:1px dashed var(--line);color:var(--muted);font-size:12px}
@media(max-width:900px){
  .topo{grid-template-columns:1fr;gap:18px}.topo-links{display:none}.tcol.mid h5{position:static}.tcol.mid{justify-content:flex-start}
}
@media(prefers-reduced-motion:reduce){.lk.ok,.lk.warn{animation:none}.tdot.ok{animation:none}}

/* collapsible sidebar */
.lbl{white-space:nowrap;transition:opacity .14s,filter .14s}
.brand,.nav h6,.nav a,.sidefoot{transition:padding .28s cubic-bezier(.77,0,.175,1),margin .28s cubic-bezier(.77,0,.175,1),font-size .28s,background-color .18s,color .18s}
.sidefoot .btn{display:inline-flex;align-items:center;gap:8px}
.sidefoot .btn svg.i{width:16px;height:16px}
.nav h6{white-space:nowrap;overflow:hidden}
.tip{position:fixed;z-index:60;pointer-events:none;background:var(--surface);color:var(--text);border:1px solid var(--line);border-radius:8px;padding:6px 10px;font-size:12.5px;font-weight:550;box-shadow:var(--shadow);transform-origin:left center;animation:pop-in .16s var(--spring)}
@media(min-width:901px){
  .app.collapsed .side{width:64px}
  .app.collapsed .lbl{opacity:0;filter:blur(2px)}
  .app.collapsed .brand{padding-left:13px;padding-right:13px}
  .app.collapsed .nav h6{font-size:0;height:1px;padding:0;margin:10px 12px 8px;background:var(--side-line)}
  .app.collapsed .nav h6:first-child{margin-top:4px;background:none}
  .app.collapsed .nav a .run{display:none}
  .app.collapsed .nav a.busy::after{content:"";position:absolute;top:8px;right:8px;width:7px;height:7px;border-radius:50%;background:var(--warn)}
  .app.collapsed .nav a:hover{transform:none}
  .app.collapsed .sidefoot{flex-direction:column;gap:8px;padding:14px 0}
  .app.collapsed .sidefoot .lbl{display:none}
  .app.collapsed .sidefoot .btn{padding:6px}
}
@media(prefers-reduced-motion:reduce){.side,.brand,.nav h6,.nav a,.sidefoot{transition:none}}
.hamb .pl{transition:transform .28s cubic-bezier(.77,0,.175,1)}
.app.collapsed .hamb .pl{transform:translateX(-3px)}
@media(prefers-reduced-motion:reduce){.hamb .pl{transition:none}}
.hamb svg.i{width:22px;height:22px}
.hamb svg.i{stroke-width:2}

/* toggle switch */
.sw{position:relative;display:inline-block;width:40px;height:23px;flex:none;cursor:pointer}
.sw input{position:absolute;inset:0;opacity:0;width:100%;height:100%;margin:0;cursor:pointer;z-index:1}
.sw span{position:absolute;inset:0;border-radius:99px;background:var(--sw-off,#cbd5e1);transition:background-color .2s var(--ease)}
.sw span::after{content:"";position:absolute;top:3px;left:3px;width:17px;height:17px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3);transition:transform .2s var(--spring),background-color .2s}
.sw input:checked+span{background:var(--accent)}
.sw input:checked+span::after{transform:translateX(17px);background:var(--on-accent)}
.sw input:focus-visible+span{outline:2px solid var(--accent);outline-offset:2px}
[data-theme=dark]{--sw-off:#404040}
.modal .box.scroll{max-height:92vh;overflow:auto;width:min(560px,94vw)}

.gate{position:fixed;inset:0;z-index:60;background:radial-gradient(900px 500px at 50% -10%,var(--accent-soft),transparent 70%),var(--bg);display:flex;align-items:center;justify-content:center;padding:20px;overflow:auto}
.gate[hidden]{display:none}
.gate-box{width:min(560px,100%);background:var(--surface);border:1px solid var(--line);border-radius:18px;box-shadow:0 20px 60px rgba(15,23,42,.14);padding:24px;display:flex;flex-direction:column;gap:14px;max-height:calc(100vh - 40px);animation:fade-up .35s var(--ease)}
.gate-head{display:flex;align-items:center;gap:12px}
.gate-head .logo{width:36px;height:36px}
.gate-head div{display:flex;flex-direction:column;line-height:1.2;flex:1}
.gate-head b{font-size:14px;letter-spacing:.06em}.gate-head span{font-size:12px;color:var(--muted)}
.gate-box h2{margin:6px 0 0;font-size:24px;font-weight:700;letter-spacing:-.01em}
.gate-search{position:relative}
.gate-search svg{position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--muted);pointer-events:none}
.gate-search .inp{max-width:none;width:100%;height:48px;padding:0 14px 0 44px;font-size:15px;border-radius:12px;background:var(--surface2)}
.gate-search .inp:focus{background:var(--surface);box-shadow:0 0 0 3px var(--accent-soft);border-color:var(--accent)}
.gate-list{overflow:auto;min-height:120px;max-height:52vh;display:flex;flex-direction:column;gap:6px;padding:2px}
.gate-list button{display:flex;align-items:center;gap:12px;width:100%;text-align:left;border:1px solid var(--line);background:var(--surface);color:var(--text);font:inherit;padding:10px 12px;border-radius:12px;cursor:pointer;transition:border-color .15s,background .15s,transform .15s}
.gate-list .av{width:38px;height:38px;border-radius:10px;background:var(--accent-soft);color:var(--accent);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px;flex:none}
.gate-list .tx{display:flex;flex-direction:column;min-width:0;flex:1}
.gate-list .tx b{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gate-list .tx small{color:var(--muted);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gate-list .tag{font-size:11px;font-weight:650;color:var(--accent);background:var(--accent-soft);border-radius:999px;padding:2px 8px;flex:none}
.gate-list .num{font-size:12px;color:var(--muted);white-space:nowrap;flex:none}
.gate-list svg.i{color:var(--muted);width:18px;height:18px}
.gate-list button.cur,.gate-list button:hover{border-color:var(--accent);background:var(--accent-soft)}
.gate-list button.cur svg.i,.gate-list button:hover svg.i{color:var(--accent);transform:translateX(2px)}
.gate-list .empty{padding:32px 0}

/* ---- Thống kê sử dụng ---- */
.seg{display:inline-flex;padding:3px;border:1px solid var(--line);border-radius:10px;background:var(--surface2);gap:2px}
.seg button{border:0;background:none;padding:6px 14px;border-radius:8px;font:inherit;font-weight:600;color:var(--muted);cursor:pointer;transition:.15s}
.seg button.on{background:var(--surface);color:var(--text);box-shadow:var(--shadow)}
.usebar{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.usebar .inp{width:auto}
.modal .box.usage{width:min(920px,96vw);max-height:92vh;overflow:auto;padding:0}
.uhead{display:flex;gap:14px;align-items:flex-start;padding:22px 24px 16px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surface);z-index:2;flex-wrap:wrap}
.uhead .ico{width:46px;height:46px;border-radius:12px;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);flex:none}
.uhead .ico svg{width:24px;height:24px}
.uhead h3{margin:0;font-size:18px;letter-spacing:-.01em}.uhead .sub{color:var(--muted);font-size:13px;margin-top:2px;display:flex;gap:6px 14px;flex-wrap:wrap}
.uhead .x{margin-left:auto}
.ubody{padding:18px 24px 24px;display:grid;gap:18px}
.usec h4{margin:0 0 10px;font-size:12.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);display:flex;align-items:center;gap:8px}
.usec h4::after{content:"";flex:1;height:1px;background:var(--line)}
.ustats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.ustat{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--surface2);display:grid;gap:3px;min-width:0;align-content:start}
.ustat .l{color:var(--muted);font-size:12.5px;display:flex;align-items:center;gap:6px}
.ustat .l i{width:8px;height:8px;border-radius:50%;background:var(--muted);flex:none}
.ustat .v{font-size:22px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.ustat .s{color:var(--muted);font-size:12px}
.ustat .bar{margin-top:6px;height:6px}
.i-ok{background:var(--ok)!important}.i-info{background:var(--accent)!important}.i-warn{background:var(--warn)!important}.i-bad{background:var(--bad)!important}.i-leave{background:#8b5cf6!important}
.stack{display:flex;height:12px;border-radius:99px;overflow:hidden;background:var(--line);margin-bottom:12px}
.stack i{display:block;height:100%;transition:width .5s var(--ease)}
.legend{display:flex;gap:6px 16px;flex-wrap:wrap;font-size:12.5px;color:var(--muted);margin-bottom:12px}
.legend span{display:inline-flex;align-items:center;gap:6px}.legend i{width:9px;height:9px;border-radius:50%}
.ustatus{display:inline-flex;align-items:center;gap:6px}
.udot{width:8px;height:8px;border-radius:50%;background:var(--muted);display:inline-block}.udot.ok{background:var(--ok)}.udot.bad{background:var(--bad)}
@media(max-width:900px){.uhead,.ubody{padding-left:16px;padding-right:16px}.usebar{width:100%}.usebar .inp{flex:1}}
.ustats.c3{grid-template-columns:repeat(3,1fr)}@media(max-width:700px){.ustats.c3{grid-template-columns:repeat(2,1fr)}}
.uclose{margin:-4px -6px 0 0;color:var(--muted)}.uclose:hover{background:var(--surface2);color:var(--text)}.uclose svg{width:22px;height:22px}

/* ---- Hàng bấm được để xem chi tiết: mũi tên cạnh tên, hover nổi màu chủ đạo ---- */
table.people.flat.click tbody tr[data-sid] td:first-child b,table.devtbl tbody tr[data-id] td.c-main b{transition:color .18s var(--ease)}
table.people.flat.click tbody tr[data-sid] td:first-child b::after,table.devtbl tbody tr[data-id] td.c-main b::after{
  content:"";display:inline-block;width:16px;height:16px;margin-left:4px;vertical-align:-3px;background:currentColor;opacity:.35;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat;
  transition:opacity .18s var(--ease),transform .18s var(--ease)}
table.people.flat.click tbody tr[data-sid]:hover td,table.devtbl tbody tr[data-id]:hover td{background:var(--accent-soft)}
table.people.flat.click tbody tr[data-sid]:hover td:first-child,table.devtbl tbody tr[data-id]:hover td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
table.people.flat.click tbody tr[data-sid]:hover td:first-child b,table.devtbl tbody tr[data-id]:hover td.c-main b{color:var(--accent)}
table.people.flat.click tbody tr[data-sid]:hover td:first-child b::after,table.devtbl tbody tr[data-id]:hover td.c-main b::after{opacity:1;transform:translateX(3px)}
[data-theme=dark] table.people.flat.click tbody tr[data-sid]:hover td:first-child b,[data-theme=dark] table.devtbl tbody tr[data-id]:hover td.c-main b{color:var(--text)}
table.people.flat.click tbody tr[data-sid]:focus-visible,table.devtbl tbody tr[data-id]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}

/* ---- Bảng danh sách hiện đại ---- */
table.people.modern{border-collapse:separate;border-spacing:0}
table.people.modern thead th{background:var(--surface2);padding:11px 14px;border-bottom:1px solid var(--line);white-space:nowrap}
table.people.modern thead th:first-child{border-radius:10px 0 0 10px}table.people.modern thead th:last-child{border-radius:0 10px 10px 0}
table.people.modern td{padding:14px;border-bottom:1px solid var(--line)}
table.people.modern tbody tr:last-child td{border-bottom:0}
table.people.modern th.c-act,table.people.modern td.c-act{text-align:right;white-space:nowrap;width:1%}
table.people.modern td.c-act{padding-right:10px}
.who2{display:flex;gap:12px;align-items:center;min-width:220px}
.who2 .av{width:38px;height:38px;border-radius:10px;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-weight:700;font-size:15px;flex:none}
.who2 b{display:inline}.who2 .sub{color:var(--muted);font-size:12.5px;margin-top:1px;max-width:420px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ibtn{display:inline-grid;place-items:center;width:34px;height:34px;margin-left:2px;border:0;border-radius:9px;background:transparent;color:var(--muted);cursor:pointer;transition:background-color .15s,color .15s}
.ibtn svg.i{width:18px;height:18px}.ibtn span{display:none}
.ibtn:hover{background:var(--surface);color:var(--text);box-shadow:inset 0 0 0 1px var(--line)}
.ibtn.danger:hover{background:var(--bad-soft);color:var(--bad);box-shadow:none}
.ibtn:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@media(max-width:900px){
  table.devtbl td.c-act .ibtn{display:inline-flex;gap:6px;width:auto;flex:1;height:38px;margin:0;border:1px solid var(--line);color:var(--text);font-weight:600}
  table.devtbl td.c-act .ibtn span{display:inline}
  table.devtbl td.c-act .ibtn.danger{color:var(--bad)}
  table.devtbl td.c-act{width:100%}
  table.people.modern.devtbl td{padding:3px 0;border-bottom:0}
  table.people.modern.devtbl td.c-sel{padding:0}
  table.people.modern.devtbl td.c-act{display:flex;gap:8px;width:100%;padding:10px 0 0;margin-top:8px;border-top:1px solid var(--line);text-align:left}
}

/* ---- Bộ lọc dạng lưới: nhãn trên ô nhập, nút cùng hàng ---- */
.fgrid{display:grid;grid-template-columns:1fr 1fr 1fr auto;gap:14px;align-items:end}
.fld{min-width:0}.fld label{display:block;font-size:12.5px;font-weight:600;color:var(--muted);margin-bottom:6px}
.fgrid .inp{height:42px}.fgrid .btn{height:42px;padding:0 22px}
.fnote{display:flex;gap:8px;align-items:center;margin-top:14px}.fnote svg.i{width:16px;height:16px;color:var(--warn)}
@media(max-width:900px){.fgrid{grid-template-columns:1fr}.fgrid .btn{width:100%}}
select.inp{appearance:none;-webkit-appearance:none;padding-right:46px;cursor:pointer;text-overflow:ellipsis;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 18px center;background-size:16px}

/* Nhãn "Đang xử lý" nằm dưới tên menu */
.nav a .lbl{display:flex;flex-direction:column;align-items:flex-start;min-width:0;line-height:1.25}
.nav a .run{margin:3px 0 0;font-size:10.5px;display:inline-flex;align-items:center;gap:5px;padding:1px 8px}
.nav a .run::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;animation:runpulse 1.2s ease-in-out infinite}
@keyframes runpulse{50%{opacity:.25}}
.cam-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.cam-head h3{margin:0 0 8px}
#camList{max-height:60vh;overflow:auto}

/* ---- Dữ liệu trên Face Terminal: thẻ máy ---- */
.mgrid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(270px,1fr))}
.mcard{padding:16px 18px;display:grid;gap:12px;align-content:start;min-width:0}
.mcard.bad{border-color:color-mix(in srgb,var(--bad) 45%,var(--line))}
.mcard.busy{border-color:color-mix(in srgb,var(--accent) 55%,var(--line));box-shadow:0 0 0 3px var(--accent-soft),var(--shadow)}
.mhd{display:flex;align-items:center;gap:10px;min-width:0}.mhd>b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mst-wrap{margin-left:auto;flex:none}
.mst{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--accent)}
.mst.wait{color:var(--muted)}
.mst .spin{width:13px;height:13px;border-radius:50%;border:2px solid var(--accent);border-top-color:transparent;animation:spin .8s linear infinite}
.mnum{font-size:30px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:8px;min-height:38px}
.mnum small{font-size:12.5px;font-weight:500;color:var(--muted);letter-spacing:0}
.mmini{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.mmini span{display:grid;gap:1px;padding:8px 10px;border-radius:10px;background:var(--surface2);border:1px solid var(--line);font-size:12px;color:var(--muted)}
.mmini span b{font-size:16px;color:var(--text);font-variant-numeric:tabular-nums}.mmini span.w b{color:var(--warn)}
.mcard .tile-acts{margin-top:0;min-height:32px}
.skel{display:block;height:1em;min-height:14px;width:70%;border-radius:6px;background:linear-gradient(90deg,var(--line),var(--surface2),var(--line));background-size:200% 100%;animation:skel 1.2s linear infinite}
.mnum .skel{height:28px;width:90px}.mmini span.skel{height:50px;width:auto;border:0}
@keyframes skel{to{background-position:-200% 0}}
.hacts{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:flex-end}

/* ---- Modal Xem người ---- */
.pstats{grid-template-columns:repeat(4,1fr)}
button.ustat{font:inherit;color:inherit;text-align:left;cursor:default}
button.ustat.tab{cursor:pointer;transition:border-color .15s,background-color .15s,box-shadow .15s}
button.ustat.tab:hover{border-color:color-mix(in srgb,var(--accent) 45%,var(--line))}
button.ustat.tab.on{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 3px var(--accent-soft)}
.ptool{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.psearch{position:relative;flex:1 1 260px;max-width:360px;display:block}
.psearch svg.i{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:17px;height:17px;color:var(--muted);pointer-events:none}
.psearch .inp{padding-left:38px;max-width:none}
.ptool .btn svg.i{width:17px;height:17px}
.pscroll{max-height:min(44vh,400px);overflow:auto;border:1px solid var(--line);border-radius:12px}
table.ptable{border-collapse:separate;border-spacing:0}
table.ptable thead th{position:sticky;top:0;z-index:1;background:var(--surface2);padding:10px 14px;border-bottom:1px solid var(--line)}
table.ptable td{padding:9px 14px;border-bottom:1px solid var(--line)}
table.ptable tbody tr:last-child td{border-bottom:0}
table.ptable tbody tr:hover td{background:var(--surface2)}
table.ptable .c-ck{width:44px}
.code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px;padding:2px 8px;border-radius:7px;background:var(--surface2);border:1px solid var(--line)}
.pp{display:flex;align-items:center;gap:10px}
.av2{width:28px;height:28px;border-radius:50%;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-weight:700;font-size:12px;flex:none}
.av2.off{background:var(--warn-soft);color:var(--warn)}
.muted{color:var(--muted)}
.pempty{padding:34px 0!important;text-align:center;color:var(--muted)}
.pav{width:44px;height:44px;border-radius:10px;overflow:hidden;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);font-weight:700;font-size:15px;flex:none;border:1px solid var(--line)}
.pav img{width:100%;height:100%;object-fit:cover;display:block}
.pav.miss::before{content:attr(data-ph)}
.pav.off{background:var(--warn-soft);color:var(--warn)}
button.pav.real{padding:0;cursor:zoom-in;border-color:var(--accent)}
table.ptable .c-peek{white-space:nowrap}
table.ptable .c-peek .btn svg.i{width:15px;height:15px}
.peekzoom{position:fixed;inset:0;z-index:35;background:rgba(10,14,22,.62);display:grid;place-items:center;padding:16px}
.peekbox{background:var(--surface);border-radius:16px;padding:14px;width:min(640px,96vw);max-height:92dvh;overflow:auto;box-shadow:0 20px 60px rgba(0,0,0,.35)}
.peekhd{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:12px}
.peekimgs{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
.peekimgs figure{margin:0;display:grid;gap:6px}
.peekimgs img{width:100%;max-height:62dvh;object-fit:contain;background:#000;border-radius:10px;display:block}
.peekimgs figcaption{color:var(--muted);font-size:12.5px;text-align:center}
@media(max-width:700px){.pstats{grid-template-columns:repeat(2,1fr)}.psearch{max-width:none}}

/* Ảnh Checkin modal */
.ck-head{display:flex;gap:12px;align-items:flex-start;justify-content:space-between;margin-bottom:14px}.ck-head h3{margin:0 0 2px}
.ck-body{max-height:70vh;overflow:auto;padding-right:4px}
.ck-day{margin-bottom:18px}.ck-day h4{margin:0 0 8px;font-size:14px}.ck-day h4 small{color:var(--muted);font-weight:500;margin-left:6px}
.ck-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
.ck-card{display:flex;flex-direction:column;padding:0;text-align:left;font:inherit;color:inherit;background:var(--surface);border:1px solid var(--line);border-radius:12px;overflow:hidden;cursor:pointer;transition:transform .15s,box-shadow .15s}
.ck-card:hover{transform:translateY(-2px);box-shadow:var(--shadow)}
.ck-card img,.ck-card .miss{width:100%;height:170px;object-fit:cover;display:grid;place-items:center;background:#0b1120;color:var(--muted)}
.ck-card .miss{background:var(--surface2);font-size:12px}
.ck-card .meta{display:flex;flex-direction:column;gap:2px;padding:8px 10px}.ck-card .meta small{color:var(--muted);font-size:12px}
.ck-view{background:#000;border-radius:12px;display:grid;place-items:center;min-height:200px}.ck-view img{max-width:100%;max-height:64vh;object-fit:contain;display:block}.ck-view .miss{color:#9aa7bd;padding:60px 0}
.ck-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:12px}.ck-bar .spacer{flex:1}
.ck-cap{display:flex;flex-direction:column;align-items:center;text-align:center;min-width:160px}.ck-cap small{color:var(--muted)}
@media(max-width:700px){.ck-grid{grid-template-columns:repeat(2,1fr)}.ck-bar .btn{flex:1}.ck-cap{order:-1;flex:1 0 100%}}

/* Ảnh Checkin: danh sách học sinh */
.ck-count{margin:14px 2px 8px;font-size:12.5px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.ck-list{display:grid;gap:8px}
.ck-row{display:flex;gap:14px;align-items:center;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:var(--surface);cursor:pointer;transition:border-color .15s,box-shadow .15s,transform .15s}
.ck-row:hover{border-color:var(--accent);box-shadow:var(--shadow);transform:translateY(-1px)}.ck-row.on{border-color:var(--accent);background:var(--accent-soft)}
.ck-av{flex:none;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;font-weight:700;font-size:15px;color:hsl(var(--h) 55% 32%);background:hsl(var(--h) 70% 90%)}
[data-theme="dark"] .ck-av{color:hsl(var(--h) 70% 82%);background:hsl(var(--h) 35% 24%)}
.ck-who{flex:1;min-width:0}.ck-who b{display:block;font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ck-tags{display:flex;gap:6px;flex-wrap:wrap;margin-top:5px}
.ck-tag{padding:2px 9px;border-radius:99px;font-size:12px;background:var(--surface2);color:var(--muted);border:1px solid var(--line)}
.ck-empty{display:flex;flex-direction:column;align-items:center;gap:6px;padding:40px 12px;text-align:center;color:var(--muted)}
.ck-empty .i{width:40px;height:40px;opacity:.55}.ck-empty b{color:var(--text);font-size:15px}
@media(max-width:700px){.ck-row{flex-wrap:wrap}.ck-row .btn{flex:1 0 100%;min-height:42px}}

/* Lịch sử điểm danh */
.ck-dates{display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap;margin-top:14px}
.ck-dates label{display:flex;flex-direction:column;gap:4px;font-size:12.5px;font-weight:600;color:var(--muted)}
.ck-dates .inp{max-width:170px;font-weight:400;color:var(--text)}
.ck-dates .hint{padding-bottom:10px}
.hm-reads{margin:0 0 14px}.hm-reads summary{cursor:pointer;color:var(--muted);font-size:13px;margin-bottom:8px}
@media(max-width:700px){.ck-dates label{flex:1}.ck-dates .inp{max-width:none}}

.ck-filter{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap}
.ck-filter .gate-search{flex:1 1 280px}
.ck-filter label{display:flex;flex-direction:column;gap:4px;font-size:12.5px;font-weight:600;color:var(--muted)}
.ck-filter label .inp{height:48px;max-width:none;width:auto;font-weight:400;color:var(--text);border-radius:12px}
@media(max-width:700px){.ck-filter label{flex:1 1 calc(50% - 6px);min-width:0}.ck-filter label:has(#histDay){flex-basis:100%}.ck-filter label .inp{width:100%}}

.ck-item{display:grid;gap:8px}
.ck-result{border:1px solid var(--line);border-radius:12px;padding:14px;background:var(--surface2)}
.ck-result .card{box-shadow:none}
.ck-row .btn[disabled]{opacity:.75;cursor:default}

/* ================= MOBILE (điện thoại) =================
   Nhắm vào nhân viên dùng điện thoại: ô nhập 16px (iOS không tự zoom), nút >= 44px, bảng thành thẻ,
   hộp thoại dạng bottom sheet, menu trượt có khóa cuộn nền, chừa vùng an toàn (tai thỏ, thanh home). */
html{-webkit-text-size-adjust:100%;overflow-x:hidden}
body{overflow-x:hidden;-webkit-tap-highlight-color:transparent}
button,.btn,.nav a,.tabs button,a{touch-action:manipulation}
body.noscroll{overflow:hidden;position:fixed;width:100%}
.tabs{overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}.tabs::-webkit-scrollbar{display:none}.tabs button{white-space:nowrap}
.table-wrap{-webkit-overflow-scrolling:touch}
@media(max-width:900px){
  .side{width:min(300px,86vw);height:100dvh;left:max(-320px,-100vw);padding-top:env(safe-area-inset-top);box-shadow:none}
  .side.open{box-shadow:0 0 40px rgba(0,0,0,.45)}
  .nav a{min-height:46px;font-size:15px}
  .nav h6{margin-top:18px}
  .sidefoot{padding-bottom:max(14px,env(safe-area-inset-bottom))}
  .sidefoot .btn{min-height:42px}
  .top{padding-top:max(10px,env(safe-area-inset-top));padding-left:max(14px,env(safe-area-inset-left));padding-right:max(14px,env(safe-area-inset-right));box-shadow:0 1px 0 var(--line)}
  .hamb{width:46px;height:46px;margin-left:-2px;flex:none;background:var(--accent);color:#fff;border-radius:12px;box-shadow:0 4px 12px color-mix(in srgb,var(--accent) 40%,transparent)}
  .hamb:hover,.hamb:active{background:color-mix(in srgb,var(--accent) 85%,#000);color:#fff}
  .hamb svg.i{stroke:#fff}
  .hamb svg.i:not(.ham-m){display:none}
  .hamb svg.ham-m{display:block;width:24px;height:24px;stroke-width:2.4;stroke-linecap:round}
  .top h1{font-size:17px}
  .view{padding-left:max(14px,env(safe-area-inset-left));padding-right:max(14px,env(safe-area-inset-right));padding-bottom:calc(96px + env(safe-area-inset-bottom))}
  .savebar{padding:12px 16px calc(12px + env(safe-area-inset-bottom));flex-wrap:wrap}
  .savebar .btn{flex:1;min-height:44px}
}
@media(max-width:700px){
  body{font-size:15px}
  .inp,select.inp,textarea.inp,input[type=number],input[type=datetime-local],input[type=date],input[type=time]{font-size:16px;min-height:44px}
  input[type=datetime-local],input[type=date],input[type=time]{-webkit-appearance:none;appearance:none;box-sizing:border-box;min-width:0;max-width:100%}
  input[type=datetime-local]::-webkit-date-and-time-value,input[type=date]::-webkit-date-and-time-value,input[type=time]::-webkit-date-and-time-value{text-align:left;min-width:0}
  .btn{min-height:44px;padding:10px 16px}
  .btn.sm{min-height:40px}
  .ibtn{width:44px;height:44px}
  .pagehead{gap:10px;margin-bottom:14px}.pagehead h2{font-size:20px}
  .pagehead>*{min-width:0}
  .card>.hd{padding:14px 14px 0;flex-wrap:wrap}.card>.bd{padding:14px}
  .tile{padding:14px}.tile .val{font-size:19px}
  .grid{gap:12px}
  .toolbar{gap:8px}
  .kv{grid-template-columns:1fr;gap:2px 0}.kv dt{font-size:12px;margin-top:8px}
  .steps .step{min-width:100%}
  .tabs{margin-left:-14px;margin-right:-14px;padding:0 14px}
  .tabs button{padding:12px 14px;min-height:44px}
  .list .it{padding:13px 0}
  .console{height:300px}
  .toasts{left:12px;right:12px;bottom:calc(84px + env(safe-area-inset-bottom))}
  .toast{min-width:0;max-width:none;width:100%}
  /* hộp thoại: giữa màn hình, cách mép một chút để dễ thao tác */
  .modal{place-items:center;padding:max(12px,env(safe-area-inset-top)) max(12px,env(safe-area-inset-right)) max(12px,env(safe-area-inset-bottom)) max(12px,env(safe-area-inset-left))}
  .modal .box,.modal .box.wide,.modal .box.xl,.modal .box.scroll,.modal .box.usage{width:100%;max-width:none;max-height:calc(100dvh - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom));overflow:auto;border-radius:16px;padding:20px 16px}
  .modal .box.usage{padding:0}
  .modal .box.lightbox{padding:6px;border-radius:14px}
  .modal .acts{flex-wrap:wrap}.modal .acts .btn{flex:1 1 40%}
  .modal label{display:block}
  .lightbox img{max-height:70dvh}
  /* bảng -> thẻ (nhãn cột lấy từ tiêu đề, gắn tự động bởi app.js) */
  table.people:not(.devtbl):not(.ptable) thead{display:none}
  table.people:not(.devtbl):not(.ptable),table.people:not(.devtbl):not(.ptable) tbody,table.people:not(.devtbl):not(.ptable) tr,table.people:not(.devtbl):not(.ptable) td{display:block;width:100%}
  table.people:not(.devtbl):not(.ptable) tr{padding:10px 12px;margin-bottom:10px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
  table.people:not(.devtbl):not(.ptable) td{border:0;padding:5px 0;min-height:0;text-align:left;display:flex;gap:10px;justify-content:space-between;align-items:flex-start;word-break:break-word}
  table.people:not(.devtbl):not(.ptable) td[data-label]::before{content:attr(data-label);color:var(--muted);font-size:12px;font-weight:600;flex:0 0 34%;max-width:34%;padding-top:2px}
  table.people:not(.devtbl):not(.ptable) td[data-label]>*{min-width:0;text-align:right}
  table.people:not(.devtbl):not(.ptable) td:empty{display:none}
  table.people:not(.devtbl):not(.ptable) tr:hover td{background:transparent}
  table.people:not(.devtbl):not(.ptable) td pre,table.people:not(.devtbl):not(.ptable) td .mono{max-width:100%}
  table.people:not(.devtbl):not(.ptable) td .who{min-width:0}
  .table-wrap{overflow:visible}
  .table-wrap[style*="max-height"]{max-height:none!important}
  /* bảng gọn trong hộp thoại (thư viện ảnh) vẫn cuộn ngang */
  .pscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
  table.ptable th,table.ptable td{padding:10px 8px}
  .ptool{flex-wrap:wrap}.ptool .btn{flex:1 1 100%}
  .pager{flex-wrap:wrap;justify-content:center}
  .pager .btn{flex:1}
}
@keyframes sheet-up{from{transform:translateY(40px);opacity:0}}
/* chọn trường + đăng nhập */
@media(max-width:700px){
  .gate{padding:0;align-items:stretch;background:var(--surface)}
  .gate-box{width:100%;max-height:none;min-height:100dvh;border:0;border-radius:0;box-shadow:none;padding:max(16px,env(safe-area-inset-top)) 16px max(16px,env(safe-area-inset-bottom))}
  .gate-box h2{font-size:22px}
  .gate-search .inp{font-size:16px;height:50px}
  .gate-list{max-height:none;flex:1}
  .gate-list button{padding:12px;min-height:60px}
  .gate-list .num{display:none}
  .login{padding:16px;align-items:start;padding-top:12vh}
  .login form{padding:22px}
}
@media(max-width:380px){.g4,#devTiles{grid-template-columns:1fr!important}}
@media(max-height:480px) and (orientation:landscape){.login{padding-top:16px}.gate{align-items:flex-start}}
@media(max-width:900px){
  .combo{width:auto;flex:1 1 0;min-width:0}
  .top h1{flex:1}
}
@media(max-width:700px){
  /* ô đầu của thẻ là tiêu đề thẻ: không nhãn, căn trái */
  table.people:not(.devtbl):not(.ptable) td:first-child{display:block;padding-bottom:8px;margin-bottom:4px;border-bottom:1px solid var(--line);font-size:15px}
  table.people:not(.devtbl):not(.ptable) td:first-child::before{display:none}
  table.people:not(.devtbl):not(.ptable) td:first-child>*{text-align:left}
  table.people:not(.devtbl):not(.ptable) td:first-child:only-child{border:0;margin:0;padding:0}
  .pagehead{align-items:stretch}
  .pagehead>div{flex:1 1 100%}
  .pagehead .btn{flex:1 1 100%}
  #devNote{word-break:break-word}
}

.scanbar{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:12px}
.scanbtn{flex-direction:column;gap:6px;min-height:76px;padding:12px 8px;font-size:15px;border-radius:12px;border-width:1.5px}
.scanbtn svg.i{width:28px;height:28px;stroke-width:1.8}
.btn.scanbtn:not(.primary){border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.scan{position:fixed;inset:0;z-index:50;background:#000;color:#fff}
.scan video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.scan-frame{position:absolute;left:50%;top:42%;width:min(86vw,520px);height:min(20vw,110px);min-height:64px;transform:translate(-50%,-50%);border:2px solid #fff;border-radius:10px;box-shadow:0 0 0 100vmax rgba(0,0,0,.55)}
.scan-top{position:absolute;top:calc(14px + env(safe-area-inset-top));right:14px}
.scan-bot{position:absolute;left:0;right:0;bottom:0;padding:16px 16px calc(20px + env(safe-area-inset-bottom));display:grid;gap:12px;justify-items:center;text-align:center;background:linear-gradient(transparent,rgba(0,0,0,.7));font-size:14px}
.pwbtn[hidden]{display:none}

.rarow{border:1px solid var(--line);border-radius:12px;margin-bottom:8px;background:var(--surface)}
.rarow summary{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 14px;cursor:pointer}
.rarow .rastat{margin-left:auto}
.rarow .rabody{padding:0 14px 14px}
.rastat .badge{display:inline-flex;align-items:center;gap:6px}.rastat .spin{width:11px;height:11px;border-radius:50%;border:2px solid var(--accent);border-top-color:transparent;animation:spin .8s linear infinite}

input[type=datetime-local].inp,input[type=date].inp,input[type=time].inp{min-height:42px;font-variant-numeric:tabular-nums;cursor:text}
[data-theme=dark] input.inp[type=datetime-local],[data-theme=dark] input.inp[type=date],[data-theme=dark] input.inp[type=time]{color-scheme:dark}
[data-theme=light] input.inp[type=datetime-local],[data-theme=light] input.inp[type=date],[data-theme=light] input.inp[type=time]{color-scheme:light}
input[type=datetime-local].inp::-webkit-datetime-edit,input[type=date].inp::-webkit-datetime-edit,input[type=time].inp::-webkit-datetime-edit{padding:0}
input[type=datetime-local].inp::-webkit-datetime-edit-fields-wrapper{padding:0}
input[type=datetime-local].inp::-webkit-datetime-edit-day-field:focus,input[type=datetime-local].inp::-webkit-datetime-edit-month-field:focus,input[type=datetime-local].inp::-webkit-datetime-edit-year-field:focus,input[type=datetime-local].inp::-webkit-datetime-edit-hour-field:focus,input[type=datetime-local].inp::-webkit-datetime-edit-minute-field:focus,input[type=datetime-local].inp::-webkit-datetime-edit-second-field:focus{background:var(--accent-soft);color:var(--text);border-radius:4px;outline:none}
input[type=datetime-local].inp::-webkit-calendar-picker-indicator,input[type=date].inp::-webkit-calendar-picker-indicator,input[type=time].inp::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.6;padding:4px;border-radius:6px}
input[type=datetime-local].inp::-webkit-calendar-picker-indicator:hover,input[type=date].inp::-webkit-calendar-picker-indicator:hover,input[type=time].inp::-webkit-calendar-picker-indicator:hover{opacity:1;background:var(--accent-soft)}

input.inp.thin{font-size:20px;font-weight:700;text-align:center;font-variant-numeric:tabular-nums;max-width:none;height:52px;-moz-appearance:textfield}
input.inp.thin::-webkit-outer-spin-button,input.inp.thin::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.chips{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.chip{min-width:48px;padding:6px 14px;border:1px solid var(--line);border-radius:999px;background:var(--surface2);color:var(--text);font:inherit;font-weight:600;cursor:pointer;transition:.15s}
.chip:hover{border-color:var(--accent);background:var(--accent-soft)}

.modal .box .mclose{float:right;position:sticky;top:0;z-index:3;margin:-8px -8px 0 10px;width:36px;height:36px;padding:0;background:var(--surface);color:var(--muted)}
.modal .box .mclose:hover{background:var(--surface2);color:var(--text)}
.modal .box .mclose svg{width:18px;height:18px}
.modal .box.usage .mclose{display:none}

.ibtn.warn{color:#ea580c}.ibtn.warn:hover{background:#fff2ed;color:#c2410c;box-shadow:none}
@media(max-width:900px){table.devtbl td.c-act .ibtn.warn{color:#ea580c}}
.volrow{display:flex;gap:12px;align-items:center;margin-top:8px}.volrow input[type=range]{flex:1;min-width:0;accent-color:var(--accent);height:28px}.volrow .inp{width:84px;flex:none;text-align:center}
.mhd .mtxt{min-width:0;display:flex;flex-direction:column;gap:1px}.mhd .mtxt>b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mhd .mtxt .mono{color:var(--muted);font-size:12px}
.spcard{margin-bottom:12px}.spcard .bd{padding:14px 16px}
.sphd{display:flex;align-items:center;gap:14px;cursor:pointer;flex-wrap:wrap}.sphd:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:8px}
.sphd .ico{display:grid;place-items:center;width:40px;height:40px;border-radius:10px;background:var(--accent-soft);color:var(--accent);flex:none}
.sphd .spmain{flex:1 1 200px;min-width:0}.sphd .spmain b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sphd .spchips{display:flex;gap:6px;flex-wrap:wrap}.sphd .spnew{white-space:nowrap}.sphd .spchev{color:var(--muted);font-size:13px;white-space:nowrap}
.spbody{margin-top:10px;border-top:1px solid var(--line);padding-top:4px}.spbody[hidden]{display:none}
.spdate{display:flex;gap:8px;align-items:center}.spdate .inp{max-width:180px}
@media(max-width:700px){.sphd{gap:10px}.sphd .spnew,.sphd .spchev{flex:1 1 40%}.spdate{flex:1 1 100%}.spdate .inp{max-width:none;flex:1}}

.mpick{display:grid;place-items:center;flex:none;cursor:pointer}.mpick input{width:18px;height:18px;margin:0;cursor:pointer;accent-color:var(--accent)}
.del-bar{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:12px;padding:10px 14px;border-radius:var(--radius);background:var(--surface2);border:1px solid var(--line)}
.del-bar .del-all{display:flex;gap:8px;align-items:center;margin-right:auto;font-size:13.5px;cursor:pointer}
.mdel:empty{display:none}
.mdel-row{display:grid;gap:6px;padding:10px 12px;border-radius:10px;background:var(--accent-soft);border:1px solid color-mix(in srgb,var(--accent) 30%,var(--line))}
.mdel-row.done{background:var(--ok-soft)}.mdel-row.failed{background:var(--bad-soft,var(--warn-soft))}.mdel-row.waiting{background:var(--surface2)}
.mdel-top{display:flex;justify-content:space-between;align-items:center;gap:10px;font-size:12.5px;min-width:0}
.mdel-top span{display:flex;align-items:center;gap:8px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mdel-top b{font-variant-numeric:tabular-nums}
.mdel-row .spin{flex:none;width:12px;height:12px;border-radius:50%;border:2px solid var(--accent);border-top-color:transparent;animation:spin .8s linear infinite}
.mdel-line{display:grid;gap:6px;margin-bottom:12px}
@media(max-width:700px){.del-bar .btn{flex:1 1 100%}}
.spgroup{border:1px solid var(--line);border-radius:10px;margin:10px 0;overflow:hidden;background:var(--surface)}
.spmsg{padding:10px 14px}
.spmsg.ack{margin-left:18px;border-left:3px solid var(--ok);background:var(--surface2);border-top:1px dashed var(--line)}
.spmeta{display:flex;flex-wrap:wrap;gap:6px 12px;align-items:center}
.spmeta .spt{white-space:nowrap;color:var(--muted)}.spmeta .spid{color:var(--muted);font-size:12px;word-break:break-all}
.sppl{margin:8px 0 0;padding:10px 12px;width:100%;max-height:240px;overflow:auto;resize:vertical;background:var(--surface2);border:1px solid var(--line);border-radius:8px;font:12px/1.55 ui-monospace,Menlo,monospace;white-space:pre-wrap;word-break:break-word}
.spmsg.ack .sppl{background:var(--surface)}
.msync:empty{display:none}.msync-acts{display:flex;gap:6px;justify-content:flex-end;margin-top:2px}.msync-acts .btn{min-height:30px}
.dtask:empty{display:none}.dtask{margin-top:4px}
.dt{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;padding:3px 8px;border-radius:8px;background:var(--surface2);color:var(--muted);max-width:100%}
.dt b{font-weight:650}.dt.run{background:var(--accent-soft);color:var(--accent)}.dt.ok{background:var(--ok-soft);color:var(--ok)}.dt.bad{background:var(--bad-soft,var(--warn-soft));color:var(--bad)}
.dt .spin{flex:none;width:12px;height:12px;border-radius:50%;border:2px solid var(--accent);border-top-color:transparent;animation:spin .8s linear infinite}.dt svg.i{width:14px;height:14px}
.tkchips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.tkchip{display:inline-flex;gap:6px;align-items:center;padding:6px 12px;border-radius:99px;border:1px solid var(--line);background:var(--surface);font:inherit;cursor:pointer}.tkchip.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.tkchip.warn b{color:var(--warn)}.tkchip.ok b{color:var(--ok)}.tkchip.bad b{color:var(--bad)}
.tkm{display:flex;gap:8px;align-items:flex-start;margin:2px 0}.tkm .badge{flex:none;margin-top:1px}.tkmt{min-width:0;word-break:break-word}
.tkd summary{cursor:pointer;font-weight:600}.tkd .tkm{margin-left:4px}
.tktable td{vertical-align:top}.tktable .badge .spin{display:inline-block;width:11px;height:11px;margin-right:6px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;animation:spin .8s linear infinite;vertical-align:-1px}
.mscope{font-size:12px;color:var(--muted,#6b7280);margin:-4px 0 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mnophoto{margin:6px 0 0}

/* ---- Test nhận diện ---- */
.ft-people{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:12px;margin-top:12px}
.ft-person{margin:0;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--surface2)}
.ft-person img{width:100%;aspect-ratio:3/4;object-fit:cover;display:block;background:var(--surface)}
.ft-person figcaption{padding:8px 10px;display:grid;gap:2px}
.ft-person figcaption .mono{font-size:11.5px;color:var(--muted)}
.ft-devs{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px}
.ft-dev{display:flex;gap:10px;align-items:center;border:1px solid var(--line);border-radius:10px;padding:8px 10px;cursor:pointer}
.ft-dev>span{display:grid;min-width:0}
.ft-dev b{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* =====================================================================
   TCPCT (Phan Chu Trinh) — bổ sung riêng, dùng chung token với schoolx.io.vn
   ===================================================================== */
.top h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
#mqttBadge{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
#mqttBadge::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor}
.nav a .cnt{margin-left:auto;font-size:11px;font-weight:650;padding:1px 8px;border-radius:99px;background:rgba(255,255,255,.1);color:var(--side-text)}
.nav a.on .cnt{background:rgba(255,255,255,.22);color:var(--side-on-text)}
.nav a .ndot{position:absolute;left:24px;top:7px;width:7px;height:7px;border-radius:50%;background:var(--muted);box-shadow:0 0 0 2px var(--side)}
.nav a .ndot.on{background:var(--ok)}
.app.collapsed .nav a .cnt{display:none}
.emo{font-size:20px;line-height:1;width:20px;text-align:center;flex:none}

/* Thẻ máy điểm danh */
.tc-grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(290px,1fr))}
.tc-dev{padding:18px 20px;display:flex;flex-direction:column;gap:14px;cursor:pointer;min-width:0;border-top:3px solid var(--line)}
.tc-dev.on{border-top-color:var(--ok)}.tc-dev.off{border-top-color:var(--muted)}
.tc-dev:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tc-dev .hd{display:flex;gap:12px;align-items:center;min-width:0}
.tc-dev .ico{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;background:var(--accent-soft);font-size:22px;flex:none}
.tc-dev .tt{min-width:0;flex:1}.tc-dev .tt b{display:block;font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tc-dev .tt small{color:var(--muted);font-size:12.5px}
.tc-dev .num{font-size:30px;font-weight:750;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1}
.tc-dev .num small{font-size:13px;font-weight:550;color:var(--muted);letter-spacing:0;margin-left:6px}
.tc-dev .ft{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding-top:12px;border-top:1px dashed var(--line);color:var(--muted);font-size:12.5px}
.tc-dev .ft .btn{margin-left:auto}

/* Thanh thao tác khi chọn học sinh */
.selbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding:10px 14px;margin-bottom:14px;border-radius:10px;background:var(--accent-soft);border:1px solid color-mix(in srgb,var(--accent) 30%,var(--line));animation:fade-up .2s var(--ease)}
.selbar b{color:var(--accent)}.selbar .spacer{flex:1}
[data-theme=dark] .selbar b{color:var(--text)}
.toolbar .grow{flex:1}
.toolbar select.inp{width:auto;min-width:150px}
.toolbar .count{color:var(--muted);font-size:13px;white-space:nowrap}

/* Ảnh đại diện học sinh trong bảng */
.who2 .av{overflow:hidden}
.who2 .av img{width:100%;height:100%;object-fit:cover;display:block;cursor:zoom-in}
.who2 .tag{display:inline-flex;margin-left:6px;vertical-align:1px}
td.c-sel,th.c-sel{width:1%;padding-right:0!important}
.mono.code{font-weight:600}
.badge.semi{background:var(--warn-soft);color:var(--warn)}
.badge.src{background:var(--surface2);color:var(--muted);border:1px solid var(--line)}
.devchips{display:flex;gap:4px;flex-wrap:wrap}
.devchips .badge{font-weight:550}
.pager .pages{display:flex;gap:4px;flex-wrap:wrap}
.pager .pages .btn{min-width:36px;padding:6px 10px}
.pager .pages .btn.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}

/* Modal thêm học sinh */
.addbar{display:flex;gap:10px;flex-wrap:wrap;margin:6px 0 12px}
.addbar .inp{flex:1;min-width:200px}
.addbar select.inp{flex:0 0 auto;width:auto;min-width:140px}
.addlist{max-height:min(56vh,520px);overflow:auto;border:1px solid var(--line);border-radius:10px}
.addlist table.people{margin:0}
.addlist thead th{position:sticky;top:0;z-index:1;background:var(--surface2)}
.ok-txt{color:var(--ok);font-weight:600;display:inline-flex;gap:4px;align-items:center;white-space:nowrap}
.ok-txt svg.i{width:16px;height:16px}
.delcard{display:flex;gap:12px;align-items:center;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:var(--surface2);margin:4px 0 12px}
.delcard .av{width:48px;height:48px;border-radius:12px;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-weight:700;overflow:hidden;flex:none}
.delcard .av img{width:100%;height:100%;object-fit:cover}
.delcard small{display:block;color:var(--muted)}
.diag{display:grid;gap:6px}
@media(max-width:900px){
  #mqttBadge{order:3}.user{display:none}
  .toolbar select.inp{flex:1 1 45%}
  .tc-dev .num{font-size:26px}
}
.toolbar .inp.grow{flex:1 1 260px;max-width:480px}
.semi-note{display:flex;gap:8px;align-items:center;margin:-8px 0 14px;color:var(--warn)}
.semi-note svg.i{width:16px;height:16px}
.tc-dev .tt .badge{margin-top:4px;font-size:11px}
@media(max-width:700px){
  .toolbar .inp.grow{flex:1 1 100%;max-width:none}
  .pagehead .btn{flex:1 1 auto;padding:10px 12px}
  .pagehead .btn.primary{flex-basis:100%}
  table.people.modern tr{position:relative}
  table.people.modern td.c-sel{position:absolute;top:12px;right:12px;width:auto;padding:0}
  table.people.modern td.c-who{padding-right:34px}
  table.people.modern td.c-act{justify-content:flex-end}
  .who2{min-width:0}
  .addlist{max-height:none;border:0}
}
