:root{--bg:#F4F4F1;--card:#FFFFFF;--line:#E6E6E1;--line2:#DADAD4;--ink:#1B1D21;--muted:#6A6D74;--gutter:#ECECE7;
--ok:#1E8A55;--load:#2457D6;--err:#B42318;--quiet:#9AA0A8;--flash:#E3EBFD;--up:#1E5BD8;--dn:#B4540A;
--add:#E7F4EC;--addb:#1F7A4D;--mod:#FFF1CC;--modb:#E2B13C;--del:#FCEDEB;--shift:#E4EAF8}
*{box-sizing:border-box}
[hidden]{display:none!important}
body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.45 "IBM Plex Sans","Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif}
.muted{color:var(--muted)}
.num{font-family:"IBM Plex Mono",ui-monospace,Menlo,Consolas,monospace;font-variant-numeric:tabular-nums}
.btn{font:inherit;font-size:13.5px;padding:9px 14px;border-radius:8px;border:1px solid #CFCFC8;background:#fff;color:var(--ink);cursor:pointer;min-height:40px;text-decoration:none;display:inline-flex;align-items:center;gap:6px}
.btn.primary{background:var(--ink);color:#fff;border-color:var(--ink)}
.btn[aria-pressed="true"]{background:#E9EDF6;border-color:#9DB0D9}
.btn:disabled{opacity:.5;cursor:default}
.form-error{color:var(--err);min-height:1.2em}
/* login */
.login-page{display:flex;min-height:100vh;align-items:center;justify-content:center;padding:16px}
.login-card{background:var(--card);border:1px solid var(--line2);border-radius:14px;padding:28px;width:100%;max-width:360px}
.login-card h1{margin:0 0 18px;font-size:20px}
.login-card form{display:flex;flex-direction:column;gap:14px}
.login-card label{display:flex;flex-direction:column;gap:6px;font-size:13px;color:#41444B}
.login-card input{font:inherit;padding:10px;border:1px solid #CFCFC8;border-radius:8px;min-height:44px}
/* top */
.topbar{background:var(--card);border-bottom:1px solid var(--line2);padding:10px 24px 0;display:flex;flex-wrap:wrap;gap:8px 16px;align-items:center;justify-content:space-between}
.brand{font-size:17px}
.brand .muted{font-size:13px;margin-left:8px}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border-radius:999px;background:#fff;border:1px solid var(--line2);font-size:12.5px}
.tabs{display:flex;gap:4px;width:100%}
.tab{font:inherit;background:none;border:0;border-bottom:2px solid transparent;padding:10px 14px;color:#55585F;cursor:pointer;min-height:44px}
.tab.on{color:var(--ink);font-weight:600;border-bottom-color:var(--ink)}
#logout{margin-left:auto}
.banner{margin:12px 24px 0;padding:10px 14px;border-radius:8px;background:#E9F2FD;border:1px solid #B9CEF0;display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.view{padding:12px 24px 32px}
.toolbar{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}
.counts{display:flex;flex-wrap:wrap;gap:14px;font-size:13px;color:#41444B;align-items:center}
.counts b{font-size:20px;color:var(--ink)}
.actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.search{display:flex;gap:8px;align-items:center;font-size:13px}
.search input{font:inherit;padding:8px 10px;border:1px solid #CFCFC8;border-radius:8px;width:150px;min-height:40px}
.hint{font-size:12.5px;color:#55585F;background:#fff;border:1px solid #E1E1DB;border-radius:8px;padding:8px 12px}
.dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex:none;background:var(--quiet)}
.dot.ok{background:var(--ok)}.dot.loading{background:var(--load)}.dot.error{background:var(--err)}.dot.quiet{background:var(--quiet)}
/* sheet */
.sheet-wrap{overflow-x:auto;background:#fff;border:1px solid var(--line2);border-radius:10px}
.sheet{min-width:1180px}
.hdr,.row{display:grid;grid-template-columns:52px 52px 76px 64px 104px 80px 100px 104px 120px 60px 96px minmax(220px,1fr);align-items:center}
.hdr{position:sticky;top:0;background:var(--gutter);border-bottom:1px solid #C9C9C2;font-size:12px;color:#4A4D55;font-weight:500;z-index:1}
.hdr>div{padding:8px 10px}
.r{text-align:right}
.row{min-height:34px;border-bottom:1px solid var(--line);font-size:13.5px;background:#fff}
.row>div{padding:0 10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row.blank{min-height:14px;background:#F7F7F4}
.row.note{color:var(--muted);font-style:italic}
.row.gs{border-top:2px solid #B9BCC4}
.row.error{background:#FFF7F5}
.row.hidden{display:none}
.rn{background:var(--gutter);color:#7A7D85;text-align:center;font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:12px;align-self:stretch;display:flex;flex-direction:column;align-items:center;justify-content:center;line-height:1.1}
.rn small{font-size:10px;color:var(--load)}
.sym{font-weight:600}
.v{text-align:right;font-family:"IBM Plex Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums;border-radius:4px;transition:background .6s}
.v.flash{background:var(--flash);transition:none}
.v.up::after{content:" ▲";color:var(--up);font-size:10px}
.v.dn::after{content:" ▼";color:var(--dn);font-size:10px}
.st{display:flex;align-items:center;gap:8px;font-size:12.5px;color:#41444B}
.row.error .st{color:#9A1F15}
.empty{padding:40px 16px;text-align:center;color:#41444B;display:flex;flex-direction:column;align-items:center;gap:12px}
.empty p{margin:0;font-size:15px}
/* diff */
.diff .row.added{background:var(--add);box-shadow:inset 3px 0 var(--addb)}
.diff .row.modified .chg{background:var(--mod);outline:1px solid var(--modb);border-radius:4px}
.diff .row.deleted{background:var(--del)}
.diff .row.deleted>div:not(.rn):not(.badge-cell){text-decoration:line-through;color:#9A6B66}
.diff .row.moved .rn{background:var(--shift)}
.old{text-decoration:line-through;color:#9A7A2E;font-size:11.5px;margin-right:4px}
.badge{display:inline-block;font-size:12px;padding:3px 8px;border-radius:999px}
.b-added{background:var(--addb);color:#fff}.b-modified{background:#F6D27A;color:#4A3500}.b-deleted{background:var(--err);color:#fff}
.upload-box{display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between;background:#fff;border:1px solid var(--line2);border-radius:10px;padding:16px}
.upload-box h2{margin:0;font-size:16px}
.file-btn input{position:absolute;left:-9999px}
.toggle{display:flex;gap:8px;align-items:center;font-size:13px}
.toggle input{width:18px;height:18px}
.preview-grid{display:flex;flex-wrap:wrap;gap:16px;align-items:flex-start;margin-top:12px}
.preview-grid>.sheet-wrap{flex:999 1 720px;min-width:0}
.side{flex:1 1 300px;max-width:380px;background:#fff;border:1px solid var(--line2);border-radius:10px;padding:14px;display:flex;flex-direction:column;gap:10px}
.side h3{margin:0;font-size:15px}
.side-actions{display:flex;flex-wrap:wrap;gap:8px}
.side-actions .btn{flex:1 1 140px;justify-content:center}
.warn{background:#FFF7F5;color:#9A1F15;border-radius:8px;padding:10px;font-size:13px}
.kv{font-size:13px;line-height:1.7}
/* mobile cards */
.cards{display:none}
.mobile-only{display:none}
@media (max-width:760px){
  .desktop-only{display:none!important}
  .mobile-only{display:block}
  .topbar,.view{padding-left:16px;padding-right:16px}
  .banner{margin:12px 16px 0}
  .sheet-wrap{display:none}
  .cards{display:flex;flex-direction:column;gap:10px;margin-top:10px}
  .card{background:#fff;border:1px solid #E1E1DB;border-radius:12px;overflow:hidden}
  .card-h{display:flex;justify-content:space-between;padding:10px 12px;background:#F7F7F4;border-bottom:1px solid #ECECE7}
  .ln{display:grid;grid-template-columns:34px 1fr auto;gap:8px;align-items:center;padding:9px 12px;border-bottom:1px solid #F0F0EC;font-size:13px}
  .ln:last-child{border-bottom:0}
  .ln .rn{border-radius:4px;padding:2px 0}
  .ln.error{background:#FFF7F5}
}
