/* ==========================================================================
   应用层组件（在 styles.css 设计系统之上）
   仅新增运行时需要的交互组件，不改动设计令牌
   ========================================================================== */

/* 页面容器（外壳由 app.js 渲染） */
.page-wrap{flex:1; min-width:0; padding:24px 24px 48px}
.page-wrap > .page{max-width:1280px}
.page--wide{max-width:none !important}
@media (max-width:900px){ .page-wrap{padding:16px 16px 40px} }

/* ------------------------------------------------------------------ Toast */
.toast-box{
  position:fixed; top:20px; left:50%; transform:translateX(-50%);
  z-index:1200; display:grid; gap:8px; justify-items:center; pointer-events:none;
}
.toast{
  background:var(--ink-900); color:#fff; font-size:13px; line-height:20px;
  padding:9px 16px; border-radius:var(--r-md); box-shadow:var(--sh-lg);
  max-width:80vw; animation:toast-in .18s ease-out;
}
.toast--success{background:var(--success-700)}
.toast--error{background:var(--danger-600)}
.toast--warn{background:var(--warning-700)}
.toast.is-out{opacity:0; transform:translateY(-6px); transition:opacity .22s, transform .22s}
@keyframes toast-in{from{opacity:0; transform:translateY(-8px)} to{opacity:1; transform:none}}

/* ------------------------------------------------------------------ Modal */
.modal-mask{
  position:fixed; inset:0; z-index:1000; background:rgba(17,24,39,.42);
  display:flex; align-items:center; justify-content:center; padding:20px;
  animation:mask-in .14s ease-out;
}
@keyframes mask-in{from{opacity:0} to{opacity:1}}
.modal{
  background:#fff; border-radius:var(--r-xl); width:100%; max-width:440px;
  box-shadow:var(--sh-xl); overflow:hidden; animation:modal-in .16s ease-out;
}
.modal--wide{max-width:720px}
@keyframes modal-in{from{opacity:0; transform:translateY(10px) scale(.99)} to{opacity:1; transform:none}}
.modal__head{padding:20px 24px 0}
.modal__body{padding:12px 24px 4px; max-height:62vh; overflow-y:auto}
.modal__text{font-size:13.5px; line-height:21px; color:var(--ink-600)}
.modal__text b{color:var(--ink-900)}
.modal__foot{display:flex; gap:10px; justify-content:flex-end; padding:18px 24px 22px}
.modal__foot .btn{min-width:88px}

/* ------------------------------------------------------------------ 工具栏 */
.toolbar{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  background:#fff; border:1px solid var(--line-200); border-radius:var(--r-lg);
  padding:12px 16px; margin-bottom:16px; box-shadow:var(--sh-xs);
}
.toolbar__search{position:relative; flex:1 1 220px; min-width:180px}
.toolbar__search svg{
  position:absolute; left:11px; top:50%; transform:translateY(-50%);
  width:15px; height:15px; color:var(--ink-400); pointer-events:none;
}
.toolbar__search .input{padding-left:33px}
.toolbar__spacer{margin-left:auto}

/* ------------------------------------------------------------------ 封面缩略图 */
.thumb-img{width:36px; height:48px; border-radius:var(--r-xs); object-fit:cover;
  border:1px solid var(--line-200); flex:0 0 36px; background:var(--bg-100)}
.thumb-lg{width:60px; height:80px; border-radius:var(--r-sm); object-fit:cover;
  border:1px solid var(--line-200); background:var(--bg-100)}

/* ------------------------------------------------------------------ 上传区 */
.dropzone{
  border:1.5px dashed var(--line-300); border-radius:var(--r-lg); background:var(--bg-50);
  padding:26px 20px; text-align:center; cursor:pointer;
  transition:border-color .14s, background .14s;
}
.dropzone:hover,.dropzone.is-over{border-color:var(--primary-600); background:var(--primary-50)}
.dropzone__title{font-size:13.5px; color:var(--ink-800); font-weight:500}
.dropzone__desc{font-size:12px; color:var(--ink-500); margin-top:5px; line-height:18px}

.upl{
  display:flex; align-items:center; gap:10px; padding:10px 12px;
  border:1px solid var(--line-200); border-radius:var(--r-md); background:#fff;
  margin-top:8px;
}
.upl__body{flex:1; min-width:0}
.upl__name{font-size:12.5px; color:var(--ink-900); font-weight:500;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.upl__meta{font-size:11.5px; color:var(--ink-400); margin-top:3px; display:flex; gap:8px; align-items:center}
.upl.is-fail{border-color:var(--danger-100); background:var(--danger-50)}
.upl.is-done{border-color:var(--success-100); background:var(--success-50)}

/* ------------------------------------------------------------------ 键值表 */
.kv{display:grid; gap:9px}
.kv__row{display:flex; align-items:baseline; gap:12px; font-size:12.5px}
.kv__k{color:var(--ink-500); flex:0 0 auto; white-space:nowrap}
.kv__v{color:var(--ink-800); font-weight:500; margin-left:auto; text-align:right;
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

/* ------------------------------------------------------------------ 分段标签页 */
.tabs{display:flex; gap:20px; border-bottom:1px solid var(--line-200); margin-bottom:16px}
.tabs__item{
  padding:10px 2px; font-size:13.5px; color:var(--ink-500); position:relative;
  background:none; border:none;
}
.tabs__item:hover{color:var(--ink-900); text-decoration:none}
.tabs__item.is-on{color:var(--primary-700); font-weight:500}
.tabs__item.is-on::after{
  content:""; position:absolute; left:0; right:0; bottom:-1px; height:2px;
  background:var(--primary-600); border-radius:2px;
}

/* ------------------------------------------------------------------ 进度条（大） */
.bar{height:8px; border-radius:var(--r-full); background:var(--bg-100); overflow:hidden}
.bar__in{height:100%; border-radius:var(--r-full); background:var(--primary-600); transition:width .3s}
.bar__in--green{background:var(--success-600)}
.bar__in--amber{background:var(--warning-600)}
.bar__in--red{background:var(--danger-600)}

/* ------------------------------------------------------------------ 图表（纯 CSS/SVG） */
.chart{width:100%; height:180px; display:block; overflow:visible}
.chart-legend{display:flex; gap:16px; flex-wrap:wrap; margin-top:12px; font-size:12px; color:var(--ink-500)}
.chart-legend i{display:inline-block; width:8px; height:8px; border-radius:2px; margin-right:5px}

.donut{display:flex; align-items:center; gap:20px; flex-wrap:wrap}
.donut__ring{width:132px; height:132px; flex:0 0 132px}
.donut__list{display:grid; gap:8px; flex:1; min-width:160px}
.donut__row{display:flex; align-items:center; gap:8px; font-size:12.5px}
.donut__dot{width:8px; height:8px; border-radius:2px; flex:0 0 8px}
.donut__name{color:var(--ink-600)}
.donut__val{margin-left:auto; color:var(--ink-900); font-weight:500; font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------------ 二维码区 */
.qr-holder{width:168px; height:168px; margin:0 auto 16px; padding:8px; background:#fff;
  border:1px solid var(--line-200); border-radius:var(--r-md); display:flex;
  align-items:center; justify-content:center}
.qr-holder img{width:100%; height:100%; object-fit:contain; image-rendering:pixelated}

/* ------------------------------------------------------------------ 手机预览 */
.phone-preview{margin:0 auto}
.phone-preview img{width:100%; display:block}

/* ------------------------------------------------------------------ H5 阅读端 */
body.h5{
  background:var(--white);
  -webkit-user-select:none; user-select:none; -webkit-touch-callout:none;
}
body.h5 img{-webkit-user-drag:none; user-drag:none; pointer-events:none}
.h5-pagebox{position:relative; background:#EEF2F7; padding:0; margin:0}
.h5-page-cv{display:block; width:100%; height:auto; background:#fff}
.h5-loading{height:180px; display:flex; align-items:center; justify-content:center;
  background:#fff; border-radius:var(--r-md); color:var(--ink-400); font-size:12.5px}
.h5-pagefail{background:#fff; border-radius:var(--r-md); padding:34px 16px; text-align:center}
.h5-pagefail .t-sm{margin-bottom:12px}
.h5-file-head{
  padding:14px 16px 10px; background:#fff; border-bottom:1px solid var(--line-100);
  position:sticky; top:0; z-index:6;
}
.h5-file-head__t{font-size:13.5px; font-weight:500; color:var(--ink-900)}
.h5-file-head__s{font-size:11.5px; color:var(--ink-400); margin-top:2px}
.h5-toc-mask{position:fixed; inset:0; background:rgba(17,24,39,.4); z-index:900;
  display:flex; align-items:flex-end; animation:mask-in .14s ease-out}
.h5-toc{background:#fff; width:100%; border-radius:16px 16px 0 0; max-height:70vh;
  overflow-y:auto; padding:8px 0 20px; animation:sheet-up .2s ease-out}
@keyframes sheet-up{from{transform:translateY(20px); opacity:.6} to{transform:none; opacity:1}}
.h5-toc__head{padding:14px 20px 8px; font-size:14px; font-weight:500; color:var(--ink-900);
  display:flex; align-items:center; border-bottom:1px solid var(--line-100); position:sticky; top:0; background:#fff}
.h5-toc__item{display:flex; align-items:center; gap:12px; padding:13px 20px;
  border-bottom:1px solid var(--line-100); color:inherit}
.h5-toc__item:last-child{border-bottom:none}
.h5-toc__item.is-on{background:var(--primary-50)}
.h5-toc__no{width:24px; height:24px; border-radius:6px; background:var(--bg-100);
  color:var(--ink-600); font-size:11.5px; display:flex; align-items:center;
  justify-content:center; flex:0 0 24px}
.h5-toc__item.is-on .h5-toc__no{background:var(--primary-600); color:#fff}
.h5-toc__name{flex:1; font-size:13.5px; color:var(--ink-900); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap}
.h5-toc__pg{font-size:11.5px; color:var(--ink-400)}

/* 水印层（H5 真实阅读页） */
.h5-wm{position:fixed; inset:0; pointer-events:none; z-index:8; overflow:hidden;
  display:flex; flex-wrap:wrap; align-content:flex-start}
.h5-wm span{display:block; width:50%; padding:22px 0; text-align:center; font-size:11px;
  color:rgba(17,24,39,.07); transform:rotate(-24deg); white-space:nowrap;
  letter-spacing:.06em; user-select:none}

/* 超长内容滚动条隐藏（微信内） */
.h5-scroll{overflow-y:auto; -webkit-overflow-scrolling:touch; flex:1}
.h5-scroll::-webkit-scrollbar{width:0; height:0}

/* 下载禁用提示 */
.no-dl-tip{display:flex; align-items:center; gap:6px; font-size:11.5px;
  color:var(--ink-400); justify-content:center; padding:10px 0 2px}

/* ------------------------------------------------------------------ 杂项 */
.row{display:flex; align-items:center; gap:12px}
.row--wrap{flex-wrap:wrap}
.grid-2{display:grid; grid-template-columns:1fr 1fr; gap:16px}
.grid-3{display:grid; grid-template-columns:repeat(3,1fr); gap:16px}
@media (max-width:900px){ .grid-2,.grid-3{grid-template-columns:1fr} }
.stack{display:grid; gap:16px}
.mt-2{margin-top:8px} .mt-3{margin-top:12px} .mt-4{margin-top:16px} .mt-5{margin-top:20px}
.mb-3{margin-bottom:12px} .mb-4{margin-bottom:16px} .mb-5{margin-bottom:20px}
.hidden{display:none !important}
.spin{display:flex; align-items:center; justify-content:center; gap:8px;
  color:var(--ink-400); font-size:13px; padding:28px}
.spin i{width:14px; height:14px; border:2px solid var(--line-300);
  border-top-color:var(--primary-600); border-radius:50%; animation:sp .7s linear infinite; display:block}
@keyframes sp{to{transform:rotate(360deg)}}
.cell-actions{display:flex; gap:12px; align-items:center; white-space:nowrap}
.link-sep{color:var(--line-300)}
.code-inline{font-family:var(--mono); font-size:12px; background:var(--bg-100);
  padding:2px 6px; border-radius:var(--r-xs); color:var(--ink-800)}
