/* ═══════════════════════════════════════════════════════════════
   DPS AI主板 v2.5 — 弹性共享布局
   页面容器、卡片网格、表格、表单、标签页、状态组件
   ═══════════════════════════════════════════════════════════════ */

/* ═══════════ 页面容器 ═══════════ */
.page-container{
  min-height:100vh;min-height:100dvh;
  display:flex;flex-direction:column;
}
.page-panel{
  max-width:min(860px, 100%);
  margin:0 auto;width:100%;
  padding:clamp(8px, 2vw, 20px);
}

/* ═══════════ 两栏布局 ═══════════ */
.app-layout{
  display:flex;
  height:100vh;height:100dvh;
  overflow:hidden;
}
.app-layout .app-sidebar{
  width:var(--sidebar-w);
  flex-shrink:0;
  border-right:1px solid var(--border);
  background:var(--bg-elevated);
  display:flex;flex-direction:column;
  overflow:hidden;
}
.app-layout .app-main{
  flex:1;min-width:0;max-width:100%;
  display:flex;flex-direction:column;
  overflow:hidden;
}

/* ═══════════ 弹性卡片网格 ═══════════ */
.card-grid{
  display:grid;
  gap:var(--gap-md);
  grid-template-columns:repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}
.card-grid-2{grid-template-columns:repeat(auto-fill, minmax(min(300px, 100%), 1fr))}
.card-grid-3{grid-template-columns:repeat(auto-fill, minmax(min(220px, 100%), 1fr))}

/* ═══════════ 表格容器 ═══════════ */
.table-wrap{
  width:100%;max-width:100%;
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  border:1px solid var(--border);
  border-radius:var(--radius-sm);
}
.table-wrap table{
  width:100%;min-width:600px;
  border-collapse:collapse;
  font-size:var(--fs-sm);
}
.table-wrap th,.table-wrap td{
  padding:clamp(6px, 1vw, 14px);
  text-align:left;border-bottom:1px solid var(--border);
  white-space:nowrap;
}
.table-wrap th{
  background:rgba(255,255,255,0.03);
  color:var(--bright);font-weight:600;
  position:sticky;top:0;
}
.table-wrap tr:hover td{background:rgba(255,255,255,0.02)}

/* ═══════════ 弹性表单 ═══════════ */
.form-grid{
  display:grid;
  gap:var(--gap-md);
  grid-template-columns:repeat(auto-fill, minmax(min(240px, 100%), 1fr));
}
.form-group{display:flex;flex-direction:column;gap:var(--gap-xs)}
.form-group label{font-size:var(--fs-sm);color:var(--dim)}
.form-group input,.form-group select,.form-group textarea{
  width:100%;max-width:100%;
  padding:8px 12px;background:var(--card);
  border:1px solid var(--border);border-radius:var(--radius-sm);
  color:var(--text);font-size:var(--fs-sm);outline:none;
}
.form-group input:focus,.form-group select:focus,.form-group textarea:focus{
  border-color:var(--primary);box-shadow:var(--shadow-input-focus);
}

/* ═══════════ 标签/徽章 ═══════════ */
.badge{
  display:inline-flex;align-items:center;gap:3px;
  padding:1px 8px;border-radius:10px;
  font-size:var(--fs-xs);font-weight:500;
}
.badge-ok{background:rgba(52,211,153,0.12);color:var(--ok)}
.badge-warn{background:rgba(251,191,36,0.12);color:var(--warn)}
.badge-err{background:rgba(255,77,90,0.12);color:var(--err)}
.badge-info{background:rgba(96,165,250,0.12);color:var(--info)}

/* ═══════════ 弹性标签页 ═══════════ */
.tab-bar{
  display:flex;gap:2px;
  overflow-x:auto;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;border-bottom:1px solid var(--border);
}
.tab-bar::-webkit-scrollbar{display:none}
.tab-btn{
  flex-shrink:0;padding:clamp(6px, 1vw, 18px);
  background:transparent;border:none;
  border-bottom:2px solid transparent;
  color:var(--dim);font-size:var(--fs-sm);
  cursor:pointer;transition:all var(--ease);white-space:nowrap;
}
.tab-btn:hover{color:var(--text)}
.tab-btn.active{color:var(--primary);border-bottom-color:var(--primary)}

/* ═══════════ 状态条 ═══════════ */
.status-bar{
  display:flex;align-items:center;gap:var(--gap-sm);
  padding:8px 14px;border-radius:var(--radius-sm);font-size:var(--fs-sm);
}
.status-bar-ok{background:rgba(52,211,153,0.08);border:1px solid rgba(52,211,153,0.2);color:var(--ok)}
.status-bar-warn{background:rgba(251,191,36,0.08);border:1px solid rgba(251,191,36,0.2);color:var(--warn)}
.status-bar-err{background:rgba(255,77,90,0.08);border:1px solid rgba(255,77,90,0.2);color:var(--err)}

/* ═══════════ 加载/空状态 ═══════════ */
.loading-state{
  display:flex;align-items:center;justify-content:center;
  padding:48px 20px;color:var(--dim);font-size:var(--fs-sm);gap:8px;
}
.loading-spinner{
  width:16px;height:16px;border:2px solid var(--border);
  border-top-color:var(--primary);border-radius:50%;
  animation:spin 0.6s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
.empty-state{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:48px 20px;color:var(--dim);font-size:var(--fs-sm);
  text-align:center;gap:var(--gap-sm);
}
.empty-state .empty-icon{font-size:32px;opacity:0.4}

/* ═══════════ 入场动画 ═══════════ */
@keyframes fadeInUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes scaleIn{from{opacity:0;transform:scale(0.95)}to{opacity:1;transform:scale(1)}}
.anim-fade-up{animation:fadeInUp 0.4s var(--ease-out) both}
.anim-fade-in{animation:fadeIn 0.3s ease both}
.anim-scale-in{animation:scaleIn 0.3s var(--ease-out) both}
.stagger>*{opacity:0;animation:fadeInUp 0.4s var(--ease-out) forwards}
.stagger>*:nth-child(1){animation-delay:0.05s}
.stagger>*:nth-child(2){animation-delay:0.1s}
.stagger>*:nth-child(3){animation-delay:0.15s}
.stagger>*:nth-child(4){animation-delay:0.2s}
.stagger>*:nth-child(5){animation-delay:0.25s}
.stagger>*:nth-child(6){animation-delay:0.3s}
.stagger>*:nth-child(7){animation-delay:0.35s}
.stagger>*:nth-child(8){animation-delay:0.4s}
