/* Vương Nhân · token + thành phần dùng chung cho Admin và 2 app.
   Nguồn: Admin Portal Concept v1 (REFERENCE-READ.md). Chỉ nền sáng (Cổng 2). */
:root{
  color-scheme: light;
  --page:#ECEBE9;
  --canvas:oklch(0.985 0.002 60);
  --surface:#FFFFFF;
  --border:oklch(0.92 0.005 60);
  --line:oklch(0.95 0.004 60);
  --control:oklch(0.88 0.006 60);
  --fill:oklch(0.97 0.003 60);
  --fill-2:oklch(0.955 0.003 60);
  --subtle:oklch(0.55 0.01 60);
  --muted:oklch(0.5 0.01 60);
  --text-2:oklch(0.42 0.01 60);
  --text:oklch(0.24 0.012 60);
  --ink:oklch(0.3 0.01 60);
  --primary:oklch(0.58 0.19 38);
  --primary-hover:oklch(0.52 0.18 38);
  --primary-soft:oklch(0.96 0.03 50);
  --primary-soft-2:oklch(0.975 0.02 55);
  --link:oklch(0.52 0.17 38);
  --nav-active:oklch(0.5 0.17 38);
  --info-bg:oklch(0.95 0.03 245);   --info:oklch(0.43 0.12 245);
  --slate-bg:oklch(0.95 0.012 260); --slate:oklch(0.45 0.04 260);
  --warn-bg:oklch(0.95 0.06 90);    --warn:oklch(0.47 0.1 75);
  --danger-bg:oklch(0.95 0.035 22); --danger:oklch(0.5 0.19 22);
  --ok-bg:oklch(0.95 0.045 148);    --ok:oklch(0.45 0.13 148);
  --neutral-bg:oklch(0.95 0.003 60);--neutral:oklch(0.48 0.01 60);
  --sched-bg:oklch(0.97 0.035 90);
  --series-1:#2a78d6; --series-2:#4a3aa7; --series-3:#e87ba4;
  --star:oklch(0.62 0.15 70);
  --r-control:8px; --r-card:12px; --r-app:16px; --r-frame:14px;
  --shadow-frame:0 1px 2px rgba(40,30,20,.06),0 16px 44px rgba(40,30,20,.10);
  --shadow-pop:0 10px 30px rgba(40,30,20,.13);
  --shadow-card:0 1px 2px rgba(40,30,20,.05),0 4px 14px rgba(40,30,20,.05);
  --shadow-drawer:-12px 0 40px rgba(30,24,18,.18);
  --scrim:rgba(30,24,18,.28);
  --ease:cubic-bezier(.2,0,0,1);
  --font:'Be Vietnam Pro',system-ui,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,monospace;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--page);font-family:var(--font);color:var(--text);-webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums;line-height:1.45}
button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
button{cursor:pointer}
a{color:var(--link);text-decoration:none}
a:hover{text-decoration:underline}
img{max-width:100%}
.ic{width:1em;height:1em;flex:none;display:inline-block;vertical-align:-.125em}
.mono{font-family:var(--mono);font-weight:500;letter-spacing:0}
.nw{white-space:nowrap}
.num{text-align:right;white-space:nowrap}
.muted{color:var(--muted)}
.subtle{color:var(--subtle)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
.link{background:none;border:0;padding:0;color:var(--link);font-weight:500;cursor:pointer;text-align:left}
.link:hover{text-decoration:underline}
.link.mono{font-weight:500}
.ok-ic{color:var(--ok)}

/* ---------- Nút ---------- */
.btn{height:36px;padding:0 14px;border-radius:var(--r-control);background:var(--surface);border:1px solid var(--control);font-size:13.5px;font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:8px;white-space:nowrap;color:var(--text);transition:background .12s var(--ease),transform .08s}
.btn:hover{background:var(--fill)}
.btn:active{transform:scale(.98)}
.btn .ic{font-size:16px}
.btn.sm{height:30px;padding:0 10px;font-size:12.5px;border-radius:7px}
.btn.lg{height:40px;padding:0 18px;font-size:14px}
.btn.primary{height:40px;min-width:120px;padding:0 20px;border:0;background:var(--primary);color:#fff;font-size:14px;font-weight:600;box-shadow:0 1px 2px rgba(180,70,20,.3)}
.btn.primary.sm{height:32px;min-width:0;font-size:13px}
.btn.primary:hover{background:var(--primary-hover)}
.btn.ghost{border-color:transparent;background:none;color:var(--link)}
.btn.ghost:hover{background:var(--primary-soft-2)}
.btn.danger{border-color:transparent;background:none;color:var(--danger)}
.btn.danger:hover{background:var(--danger-bg)}
.btn.danger-solid{border:0;background:var(--danger);color:#fff;font-weight:600;height:40px;padding:0 20px}
.btn.danger-outline{border-color:oklch(0.85 0.06 22);color:var(--danger);background:var(--surface)}
.btn.danger-outline:hover{background:var(--danger-bg)}
.btn[aria-disabled="true"],.btn:disabled{opacity:.45;cursor:not-allowed;transform:none;box-shadow:none}
.btn.primary[aria-disabled="true"],.btn.primary:disabled{background:oklch(0.8 0.08 45);opacity:1;color:#fff}
.iconbtn{position:relative;width:36px;height:36px;border-radius:var(--r-control);border:1px solid var(--border);background:var(--surface);display:inline-flex;align-items:center;justify-content:center;font-size:18px;color:var(--text-2)}
.iconbtn:hover{background:var(--fill)}
.iconbtn .dot{position:absolute;top:6px;right:7px;width:8px;height:8px;border-radius:4px;background:var(--primary);border:2px solid #fff}

/* Tooltip cho thao tác bị khoá và ⓘ */
[data-tip]{position:relative}
[data-tip]:hover::after,[data-tip]:focus-visible::after{content:attr(data-tip);position:absolute;z-index:60;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);width:max-content;max-width:280px;white-space:normal;text-align:left;background:var(--text);color:#fff;font-size:12.5px;font-weight:400;line-height:1.45;padding:7px 10px;border-radius:7px;pointer-events:none;box-shadow:var(--shadow-pop)}
[data-tip-pos="bottom"]:hover::after,[data-tip-pos="bottom"]:focus-visible::after{bottom:auto;top:calc(100% + 8px)}
[data-tip-pos="left"]:hover::after,[data-tip-pos="left"]:focus-visible::after{left:auto;right:0;transform:none}
[data-tip-pos="right"]:hover::after,[data-tip-pos="right"]:focus-visible::after{left:0;transform:none}
.info-dot{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:9px;border:0;background:none;color:var(--subtle);font-size:15px;padding:0;cursor:help}

/* ---------- Badge (TONE) ---------- */
.badge{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 9px;border-radius:999px;font-size:12px;font-weight:500;white-space:nowrap;line-height:1}
.badge::before{content:"";width:6px;height:6px;border-radius:3px;background:currentColor;flex:none}
.badge.lg{height:30px;padding:0 12px;font-size:13.5px;font-weight:600}
.badge.plain::before{display:none}
.t-info{background:var(--info-bg);color:var(--info)}
.t-slate{background:var(--slate-bg);color:var(--slate)}
.t-warn{background:var(--warn-bg);color:var(--warn)}
.t-danger{background:var(--danger-bg);color:var(--danger)}
.t-ok{background:var(--ok-bg);color:var(--ok)}
.t-neutral{background:var(--neutral-bg);color:var(--neutral)}
.pulse::before{animation:pulse 1.4s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}
.assume{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 8px;border-radius:6px;background:var(--sched-bg);color:var(--warn);font-size:11.5px;font-weight:600;white-space:nowrap}

/* ---------- Thẻ, bảng ---------- */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-card)}
.card-h{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 20px 0}
.card-h h3,.card-h h2{margin:0;font-size:15px;font-weight:600}
.card-b{padding:16px 20px 18px}
.lbl{font-size:11.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.kv{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:14px 22px}
.kv>div{display:flex;flex-direction:column;gap:3px;min-width:0}
.kv span{font-size:12px;color:var(--muted)}
.kv b{font-size:13.5px;font-weight:400;overflow-wrap:anywhere}
.row-kv{display:flex;justify-content:space-between;gap:12px;font-size:13.5px;padding:3px 0}
.row-kv span:first-child{color:var(--text-2)}
.row-kv b{font-weight:500;white-space:nowrap}
.tbl{width:100%;border-collapse:collapse;font-size:13px}
.tbl th{height:40px;padding:0 14px;text-align:left;background:oklch(0.98 0.002 60);border-bottom:1px solid var(--border);font-size:11.5px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;white-space:nowrap}
.tbl th.num,.tbl td.num{text-align:right}
.tbl th button{all:unset;cursor:pointer;display:inline-flex;align-items:center;gap:4px}
.tbl th button:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:3px}
.tbl th .ic{font-size:12px}
.tbl td{height:50px;padding:0 14px;border-bottom:1px solid var(--line);vertical-align:middle}
.tbl tr:last-child td{border-bottom:0}
.tbl tbody tr.click{cursor:pointer}
.tbl tbody tr.click:hover{background:oklch(0.985 0.01 60)}
.tbl tbody tr.sel{background:var(--primary-soft-2);box-shadow:inset 3px 0 0 var(--primary)}
.tbl tfoot td{height:46px;font-weight:600;background:oklch(0.98 0.002 60);border-top:1px solid var(--border);border-bottom:0}
.tbl .ell{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tbl .id{font:500 12px var(--mono);color:var(--text-2);white-space:nowrap}
.tbl-foot{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;font-size:12.5px;color:var(--muted);border-top:1px solid var(--line)}
.pager{display:flex;gap:4px}
.pager span,.pager button{min-width:30px;height:30px;padding:0 8px;border-radius:6px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border);background:var(--surface);font-size:12.5px}
.pager .on{background:var(--text);color:#fff;border-color:var(--text);font-weight:500}
.empty{padding:40px 20px;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;color:var(--text-2)}
.empty .ic{font-size:30px;color:var(--subtle)}
.empty b{font-size:14.5px;color:var(--text);font-weight:600}
.empty p{margin:0;font-size:13px;max-width:360px}
.skel{border-radius:6px;background:linear-gradient(90deg,var(--fill) 25%,var(--line) 50%,var(--fill) 75%);background-size:200% 100%;animation:skel 1.2s linear infinite}
@keyframes skel{to{background-position:-200% 0}}

/* ---------- Form ---------- */
.field{display:flex;flex-direction:column;gap:6px;min-width:0}
.field>label,.field>.flabel{font-size:13px;font-weight:500}
.field .req{color:var(--danger)}
.field .hint{font-size:12px;color:var(--muted)}
.field .err{font-size:12px;color:var(--danger)}
.inp,.sel,.txa{width:100%;height:38px;border-radius:var(--r-control);border:1px solid var(--control);background:var(--surface);padding:0 12px;font-size:13.5px;outline:0;transition:border-color .12s,box-shadow .12s}
.txa{height:auto;min-height:76px;padding:9px 12px;resize:vertical;line-height:1.5}
.sel{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);background-position:calc(100% - 16px) 16px,calc(100% - 11px) 16px;background-size:5px 5px;background-repeat:no-repeat;padding-right:30px}
.inp:focus,.sel:focus,.txa:focus{border:2px solid var(--primary);box-shadow:0 0 0 3px oklch(0.94 0.04 50);padding-left:11px}
.txa:focus{padding-top:8px}
.inp:disabled,.sel:disabled,.txa:disabled{background:var(--fill);color:var(--muted);cursor:not-allowed}
.field>.seg{align-self:flex-start}
.inp.bad{border-color:oklch(0.55 0.19 22)}
.inp-wrap{position:relative}
.inp-wrap .suffix{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:13px;color:var(--muted);pointer-events:none}
.inp-wrap .inp{padding-right:36px}
.search-box{position:relative;display:flex;align-items:center}
.search-box .ic{position:absolute;left:11px;font-size:16px;color:var(--subtle);pointer-events:none}
.search-box .inp{padding-left:34px}
.search-box .inp:focus{padding-left:33px}
.chk{display:flex;align-items:flex-start;gap:9px;font-size:13.5px;cursor:pointer;line-height:1.45}
.chk input{width:16px;height:16px;margin:2px 0 0;accent-color:var(--primary);flex:none}
.radios{display:flex;flex-direction:column;gap:8px}
.radio-card{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--r-control);cursor:pointer;font-size:13.5px}
.radio-card:has(input:checked){border-color:var(--primary);background:var(--primary-soft-2)}
.radio-card input{margin:3px 0 0;accent-color:var(--primary)}
.seg{height:36px;display:inline-flex;padding:3px;border-radius:var(--r-control);background:var(--fill-2);gap:2px}
.seg button{height:30px;min-width:34px;padding:0 10px;border:0;border-radius:6px;font-size:12.5px;font-weight:600;background:transparent;color:var(--muted);white-space:nowrap}
.seg button.on{background:var(--surface);color:var(--text);box-shadow:0 1px 2px rgba(40,30,20,.12)}
.switch{position:relative;width:40px;height:24px;border-radius:12px;border:0;background:var(--control);flex:none;padding:0;transition:background .15s var(--ease)}
.switch::after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:9px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.2);transition:transform .15s var(--ease)}
.switch[aria-checked="true"]{background:var(--ok)}
.switch[aria-checked="true"]::after{transform:translateX(16px)}

/* ---------- Khối tác động, cảnh báo ---------- */
.impact{border:1px solid var(--border);border-radius:10px;overflow:hidden}
.impact-h{padding:9px 12px;font-size:12px;font-weight:600;background:oklch(0.98 0.002 60);border-bottom:1px solid var(--line);color:var(--text-2);display:flex;justify-content:space-between}
.impact table{width:100%;border-collapse:collapse;font-size:13px}
.impact td{padding:8px 12px;border-top:1px solid var(--line)}
.impact tr:first-child td{border-top:0}
.impact td.num{font-variant-numeric:tabular-nums}
.impact .arrow{color:var(--subtle);padding:8px 4px;width:16px;text-align:center}
.impact .chg{font-weight:600}
.impact .up{color:var(--ok)}
.impact .dn{color:var(--danger)}
.note{display:flex;gap:10px;padding:12px 14px;border-radius:10px;font-size:13px;line-height:1.5}
.note .ic{font-size:18px;margin-top:1px}
.note.warn{background:var(--sched-bg);color:oklch(0.38 0.08 75)}
.note.danger{background:var(--danger-bg);color:oklch(0.42 0.17 22)}
.note.info{background:var(--info-bg);color:oklch(0.36 0.1 245)}
.note.ok{background:var(--ok-bg);color:oklch(0.36 0.11 148)}
.note.neutral{background:var(--fill);color:var(--text-2)}
.note b{font-weight:600}

/* ---------- Timeline (đường liền nối mốc) ---------- */
.tl{display:flex;flex-direction:column}
.tl-i{display:grid;grid-template-columns:18px minmax(0,1fr) auto;gap:14px;min-height:38px}
.tl-i .rail{display:flex;flex-direction:column;align-items:center}
.tl-i .dot{width:12px;height:12px;border-radius:6px;margin-top:4px;flex:none;box-sizing:border-box;background:var(--ink);border:2px solid var(--ink)}
.tl-i .bar{flex:1;width:2px;margin:3px 0;background:var(--ink)}
.tl-i.now .dot{background:#fff;border:3px solid var(--info);width:14px;height:14px;margin-top:3px}
.tl-i.now .dot{animation:ring 1.6s ease-in-out infinite}
@keyframes ring{0%,100%{box-shadow:0 0 0 0 oklch(0.8 0.08 245 / .7)}50%{box-shadow:0 0 0 5px oklch(0.8 0.08 245 / 0)}}
.tl-i.todo .dot{background:#fff;border:2px solid oklch(0.85 0.005 60)}
.tl-i.now .bar,.tl-i.todo .bar{background:oklch(0.9 0.004 60)}
.tl-i.red .dot{background:var(--danger);border-color:var(--danger)}
.tl-i.manual .dot{background:#fff;border:2px solid var(--warn)}
.tl-i:last-child .bar{background:transparent}
.tl-i .t{font-size:13.5px;line-height:20px;padding-bottom:10px}
.tl-i .t small{display:block;font-size:12px;color:var(--muted);line-height:1.45}
.tl-i.now .t{font-weight:600}
.tl-i.todo .t{color:var(--subtle)}
.tl-i .tm{font-size:12.5px;line-height:20px;color:var(--muted);white-space:nowrap}
.tl-i .zap{color:var(--warn);font-size:14px;vertical-align:-2px;margin-right:2px}

/* ---------- Ảnh placeholder trung thực ---------- */
.photo{position:relative;border-radius:10px;overflow:hidden;background:repeating-linear-gradient(135deg,oklch(0.965 0.006 60) 0 8px,oklch(0.94 0.008 60) 8px 16px);display:flex;align-items:flex-end;padding:8px;min-height:60px}
.photo>span{font:500 10.5px/1.4 var(--mono);background:rgba(255,255,255,.93);padding:2px 6px;border-radius:4px;color:var(--text-2)}
.photo.empty-ph{background:var(--fill);border:1.5px dashed var(--control);align-items:center;justify-content:center;color:var(--subtle);font-size:12.5px}

/* ---------- Lớp phủ: modal, drawer, menu, toast ---------- */
.scrim{position:fixed;inset:0;background:var(--scrim);z-index:40;animation:fade .15s var(--ease)}
.modal{position:fixed;z-index:41;left:50%;top:50%;transform:translate(-50%,-50%);width:min(520px,calc(100vw - 32px));max-height:calc(100vh - 48px);background:var(--surface);border-radius:14px;box-shadow:0 24px 60px rgba(30,24,18,.25);display:flex;flex-direction:column;animation:pop .16s var(--ease)}
.modal.wide{width:min(760px,calc(100vw - 32px))}
.modal-h{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:20px 22px 12px}
.modal-h h2{margin:0;font-size:18px;font-weight:600;letter-spacing:-.01em}
.modal-h p{margin:4px 0 0;font-size:13px;color:var(--muted);line-height:1.5}
.modal-b{padding:6px 22px 18px;overflow:auto;display:flex;flex-direction:column;gap:16px}
.modal-f{padding:14px 22px;border-top:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;gap:10px}
.modal-f .r{display:flex;gap:8px;margin-left:auto}
.xbtn{flex:none;width:32px;height:32px;border-radius:8px;border:1px solid var(--border);background:var(--surface);display:inline-flex;align-items:center;justify-content:center;font-size:16px;color:var(--text-2)}
.xbtn:hover{background:var(--fill)}
.drawer{position:fixed;z-index:41;top:0;right:0;bottom:0;width:min(440px,100vw);background:var(--surface);box-shadow:var(--shadow-drawer);display:flex;flex-direction:column;animation:slide .18s var(--ease)}
.drawer.wide{width:min(560px,100vw)}
.drawer .modal-h{padding:22px 24px 16px;border-bottom:1px solid var(--line)}
.drawer .modal-b{flex:1;padding:18px 24px}
.drawer .modal-f{padding:16px 24px}
@keyframes fade{from{opacity:0}}
@keyframes pop{from{opacity:0;transform:translate(-50%,-48%)}}
@keyframes slide{from{transform:translateX(24px);opacity:.3}}
.menu{position:absolute;z-index:30;min-width:240px;background:var(--surface);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;animation:fade .12s var(--ease)}
.menu button{all:unset;box-sizing:border-box;padding:9px 10px;border-radius:6px;font-size:13.5px;cursor:pointer;display:flex;flex-direction:column;gap:2px}
.menu button:hover,.menu button:focus-visible{background:var(--fill)}
.menu button.dz{color:var(--danger);font-weight:500}
.menu button.dz:hover{background:var(--danger-bg)}
.menu button[aria-disabled="true"]{color:var(--subtle);cursor:not-allowed}
.menu button small{font-size:12px;color:var(--muted);line-height:1.4;white-space:normal}
.menu hr{border:0;border-top:1px solid var(--line);margin:4px 0}
.toasts{position:fixed;top:16px;right:16px;z-index:80;display:flex;flex-direction:column;gap:8px;pointer-events:none}
.toast{min-width:280px;max-width:420px;display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border-radius:10px;background:var(--text);color:#fff;font-size:13.5px;line-height:1.45;box-shadow:0 12px 30px rgba(30,24,18,.28);animation:toast .2s var(--ease)}
.toast .ic{font-size:18px;color:oklch(0.82 0.13 148);margin-top:1px}
.toast.err .ic{color:oklch(0.78 0.12 22)}
@keyframes toast{from{opacity:0;transform:translateY(-8px)}}
.flash{animation:flash 1.2s var(--ease)}
@keyframes flash{0%{background:oklch(0.95 0.06 90)}100%{background:transparent}}

/* Khung chờ tải và vòng quay: chỉ animate opacity/transform */
.sk{display:block;height:12px;border-radius:6px;background:var(--fill-2);animation:skp 1.1s ease-in-out infinite alternate}
@keyframes skp{from{opacity:1}to{opacity:.45}}
.spin{animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media (pointer:coarse){.seg{height:auto}.seg button{height:44px;min-width:48px}}

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