/* 渡口 Portus 控制台样式 —— 全部走设计变量，不写魔法值 */
:root{
  --c-primary:#2563eb; --c-primary-hover:#1d4ed8;
  --c-bg:#0f172a;      --c-surface:#1e293b;  --c-surface-2:#273449;
  --c-text:#e2e8f0;    --c-text-muted:#94a3b8;
  --c-border:#334155;
  --c-success:#22c55e; --c-warning:#f59e0b; --c-danger:#ef4444;

  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-6:24px; --sp-8:32px;
  --fs-xs:12px; --fs-sm:14px; --fs-base:16px; --fs-lg:20px; --fs-xl:24px; --fs-2xl:32px;
  --r-sm:6px; --r-md:10px; --r-lg:16px; --r-full:999px;
  --sh-1:0 1px 2px rgba(0,0,0,.3); --sh-2:0 4px 12px rgba(0,0,0,.35);
  --t-fast:120ms; --t-base:200ms; --ease:cubic-bezier(.4,0,.2,1);
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
  background:var(--c-bg); color:var(--c-text);
  font:var(--fs-sm)/1.6 'NSimSun','SimSun','宋体','新宋体',serif;
}
.hidden{display:none !important}
.muted{color:var(--c-text-muted)}
code,pre{font-family:Consolas,"Cascadia Mono",monospace}

/* ---------- 通用控件 ---------- */
.card{
  background:var(--c-surface); border:1px solid var(--c-border);
  border-radius:var(--r-md); padding:var(--sp-6); box-shadow:var(--sh-1);
}
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  min-height:38px; padding:0 var(--sp-4); border-radius:var(--r-sm);
  border:1px solid var(--c-border); background:var(--c-surface-2); color:var(--c-text);
  font-size:var(--fs-sm); cursor:pointer; transition:background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease);
}
.btn:hover{background:#31415c}
.btn:focus-visible{outline:2px solid var(--c-primary); outline-offset:2px}
.btn.primary{background:var(--c-primary); border-color:var(--c-primary); color:#fff}
.btn.primary:hover{background:var(--c-primary-hover); border-color:var(--c-primary-hover)}
.btn.ghost{background:transparent}
.btn.danger{color:var(--c-danger); border-color:var(--c-danger)}
.btn:disabled{opacity:.5; cursor:not-allowed}

.field{display:flex; flex-direction:column; gap:var(--sp-2); font-size:var(--fs-sm)}
.field>span{color:var(--c-text-muted)}
input,select{
  min-height:38px; padding:0 var(--sp-3); border-radius:var(--r-sm);
  border:1px solid var(--c-border); background:#0c1526; color:var(--c-text);
  font-size:var(--fs-sm); transition:border-color var(--t-fast) var(--ease);
}
input:focus,select:focus{outline:none; border-color:var(--c-primary)}
.msg{min-height:20px; font-size:var(--fs-sm); margin:var(--sp-2) 0 0}
.msg.ok{color:var(--c-success)}
.msg.err{color:var(--c-danger)}
.grid-2{display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:var(--sp-4)}
.row-actions{display:flex; gap:var(--sp-2); flex-wrap:wrap; align-items:center}
.row-actions.end{justify-content:flex-end; margin-top:var(--sp-4)}
.row-head{display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4); flex-wrap:wrap}

/* ---------- 登录 ---------- */
.login-wrap{display:grid; place-items:center; min-height:100vh; padding:var(--sp-4)}
.login-card{width:min(420px,100%); display:flex; flex-direction:column; gap:var(--sp-4)}
.brand{margin:0; font-size:var(--fs-2xl); letter-spacing:.06em}
.brand span,.brand-sm span{color:var(--c-primary)}
.login-card .muted{margin:0}

/* ---------- 顶栏 ---------- */
.topbar{
  display:flex; align-items:center; gap:var(--sp-6); flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-6); background:var(--c-surface); border-bottom:1px solid var(--c-border);
}
.brand-sm{font-size:var(--fs-lg); font-weight:600}
.tabs{display:flex; gap:var(--sp-1); margin-inline-end:auto}
.tab{
  padding:var(--sp-2) var(--sp-4); border:0; border-radius:var(--r-sm); cursor:pointer;
  background:transparent; color:var(--c-text); font-size:var(--fs-sm);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
.tab:hover{background:var(--c-surface-2); color:var(--c-text)}
.tab.active{background:var(--c-primary); color:#fff}
.content{max-width:1280px; margin-inline:auto; padding:var(--sp-6); display:flex; flex-direction:column; gap:var(--sp-4)}
.panel{display:flex; flex-direction:column; gap:var(--sp-4)}
h2{font-size:var(--fs-lg); margin:0 0 var(--sp-3)}
h3{font-size:var(--fs-base); margin:0 0 var(--sp-4)}

/* ---------- 统计卡片 ---------- */
.stat-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:var(--sp-4)}
.stat{display:flex; flex-direction:column; gap:var(--sp-1); padding:var(--sp-4) var(--sp-6)}
.stat-label{font-size:var(--fs-sm); color:var(--c-text-muted)}
.stat strong{font-size:var(--fs-2xl); line-height:1.2}

/* ---------- 表格 ---------- */
.table-wrap{overflow-x:auto; margin-top:var(--sp-3)}
table{width:100%; border-collapse:collapse; font-size:var(--fs-sm); min-width:900px}
th,td{padding:var(--sp-3) var(--sp-3); text-align:left; border-bottom:1px solid var(--c-border); white-space:nowrap}
th{color:var(--c-text-muted); font-weight:500}
tbody tr:hover{background:var(--c-surface-2)}
.dot{display:inline-block; inline-size:8px; block-size:8px; border-radius:var(--r-full); margin-inline-end:var(--sp-2)}
.dot.on{background:var(--c-success)} .dot.off{background:#64748b}
.code{background:#0c1526; border:1px solid var(--c-border); border-radius:var(--r-sm);
  padding:var(--sp-3); overflow-x:auto; font-size:var(--fs-xs); margin-top:var(--sp-3)}
.pill{display:inline-block; padding:2px var(--sp-2); border-radius:var(--r-full); font-size:var(--fs-xs)}
.pill.warn{background:rgba(245,158,11,.15); color:var(--c-warning)}

/* ---------- 弹窗 ---------- */
.modal{position:fixed; inset:0; display:grid; place-items:center; background:rgba(2,6,23,.7); padding:var(--sp-4); z-index:50}
.modal-card{width:min(520px,100%); display:flex; flex-direction:column; gap:var(--sp-3); max-height:90vh; overflow-y:auto}

@media (max-width:640px){
  .topbar{padding:var(--sp-3)}
  .content{padding:var(--sp-4)}
  .tabs{width:100%; order:3}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none !important}
}

.muted.small{font-size:var(--fs-xs);line-height:1.5;margin-top:calc(-1 * var(--sp-1))}

/* ---------- 动效层（追加于基线之后，类名/DOM/原有 JS 零改动） ---------- */
@keyframes fadeUp{
  from{opacity:0; transform:translateY(14px)}
  to{opacity:1; transform:none}
}

/* 首屏登录卡：子元素错峰入场（animation-delay 递增；backwards 只回填延迟期，结束后不锁 transform） */
.login-card>*{animation:fadeUp .45s cubic-bezier(.16,1,.3,1) backwards}
.login-card>*:nth-child(1){animation-delay:.00s}
.login-card>*:nth-child(2){animation-delay:.06s}
.login-card>*:nth-child(3){animation-delay:.12s}
.login-card>*:nth-child(4){animation-delay:.18s}
.login-card>*:nth-child(5){animation-delay:.24s}
.login-card>*:nth-child(6){animation-delay:.30s}
.login-card>*:nth-child(7){animation-delay:.36s}
.login-card>*:nth-child(8){animation-delay:.42s}

/* 区块显现：.reveal 由动效层 JS 挂载，JS 不可用时类不存在，内容照常可见 */
.reveal{opacity:0; transform:translateY(14px); transition:opacity .55s var(--ease),transform .55s var(--ease)}
.reveal.in{opacity:1; transform:none}

/* 按钮/标签七态补全（focus-visible / active / disabled） */
.btn:not(:disabled):focus-visible{outline:2px solid var(--c-primary); outline-offset:2px}
.tab:focus-visible,a:focus-visible{outline:2px solid var(--c-primary); outline-offset:2px}
.btn:not(:disabled):hover{transform:translateY(-1px); box-shadow:var(--sh-2)}
.tab:not(.active):hover{transform:translateY(-1px)}
.btn:not(:disabled):active{transform:scale(.97)}
.btn:disabled,.btn.disabled,.btn[disabled]{opacity:.5; cursor:not-allowed}

/* transition 只动 transform/opacity/color/border-color/box-shadow（禁 transition:all） */
.btn:not(:disabled){transition:background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.tab{transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.stat{transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.stat:hover{transform:translateY(-2px); box-shadow:var(--sh-2)}

/* 主操作按钮触控尺寸 */
.btn.primary{min-height:44px}

/* 无障碍：用户要求减少动效时全部关闭 */
@media (prefers-reduced-motion:reduce){
  *{animation:none !important; transition:none !important}
}

/* ---------- 细节增强层（追加于动效层之后，原行零改动） ---------- */

/* 1. 自定义滚动条：thumb 半透明主色 + hover 加深，track 透明 */
::-webkit-scrollbar{width:9px; height:9px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(37,99,235,.35); border-radius:var(--r-full)}
::-webkit-scrollbar-thumb:hover{background:rgba(37,99,235,.55)}

/* 2. 表单 focus 发光环（原 border-color 高亮保留） */
input:focus,select:focus,textarea:focus{box-shadow:0 0 0 3px rgba(37,99,235,.18)}

/* 3. 按钮微交互：hover 阴影强化 + active 明显缩放（覆盖动效层 .97 → .96） */
.btn:not(:disabled):hover{box-shadow:var(--sh-2),0 6px 16px rgba(2,6,23,.45)}
.btn:not(:disabled):active{transform:scale(.96)}

/* 4. 卡片 hover：border 高亮 + inset 内发光（.reveal/.stat 各自 transition 保留，不覆盖入场动效） */
.card:not(.stat):not(.reveal){transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-base) var(--ease)}
.card.reveal{transition:opacity .55s var(--ease),transform .55s var(--ease),border-color var(--t-fast) var(--ease),box-shadow var(--t-base) var(--ease)}
.card:hover{border-color:rgba(37,99,235,.55); box-shadow:var(--sh-2),inset 0 0 14px rgba(37,99,235,.12)}

/* 5. 骨架 shimmer：页面无加载容器，跳过 */
/* 6. 弹窗入场：遮罩淡入 + 卡片 scale 入场（页面无 toast 类，仅 modal） */
@keyframes backdropIn{from{opacity:0} to{opacity:1}}
@keyframes modalIn{from{opacity:0; transform:scale(.96)} to{opacity:1; transform:none}}
.modal{animation:backdropIn .25s var(--ease)}
.modal-card{animation:modalIn .25s var(--ease)}

/* 7. 表格 zebra + 行 hover（hover 重声明在后，压过 even 底纹） */
tbody tr:nth-child(even){background:rgba(148,163,184,.06)}
tbody tr:hover{background:var(--c-surface-2)}

/* 8. 主题切换过渡 */
body{transition:background-color .3s ease,color .3s ease}

/* 9. reduced-motion：新动画/过渡类显式兜底（既有 * 通配块已全覆盖） */
@media (prefers-reduced-motion:reduce){
  .modal,.modal-card{animation:none !important}
  .card,.btn,body{transition:none !important}
}
