/* ============================================================
   华云设计系统 · 组件层 Components
   规则：只引用 tokens.css 的语义别名，不出现任何字面色值
   ============================================================ */

*{box-sizing:border-box}
html{background:var(--bg-app)}
body{
  margin:0; background:var(--bg-app); color:var(--fg);
  font-family:var(--font-sans); font-size:var(--t-md); line-height:var(--lh-md);
  -webkit-font-smoothing:antialiased;
}
:where(a){color:var(--fg-brand)}
:focus-visible{outline:2px solid var(--b-500); outline-offset:2px; border-radius:var(--r-xs)}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
.num{font-variant-numeric:tabular-nums}

/* ============ E-01 按钮 Button ============ */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--s-3);
  height:var(--h-ctl); padding:0 var(--s-5); border-radius:var(--r-md);
  font:inherit; font-size:var(--t-md); font-weight:var(--w-semibold);
  border:1px solid transparent; cursor:pointer; white-space:nowrap;
  transition:background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.btn:focus-visible{outline:none; box-shadow:var(--ring)}
.btn:disabled{cursor:not-allowed; opacity:.5}
.btn-sm{height:var(--h-ctl-sm); padding:0 var(--s-4); font-size:var(--t-sm)}
.btn-lg{height:var(--h-ctl-lg); padding:0 var(--s-6); font-size:var(--t-lg)}

.btn-primary{background:var(--b-500); color:var(--n-0); border-color:var(--b-500); box-shadow:var(--sh-xs)}
.btn-primary:hover:not(:disabled){background:var(--b-600); border-color:var(--b-600)}
.btn-primary:active:not(:disabled){background:var(--b-700)}
:root[data-theme="dark"] .btn-primary{color:var(--n-25)}

.btn-secondary{background:var(--bg-surface); color:var(--fg); border-color:var(--bd); box-shadow:var(--sh-xs)}
.btn-secondary:hover:not(:disabled){background:var(--bg-hover); border-color:var(--bd-strong)}

.btn-ghost{background:transparent; color:var(--fg-soft)}
.btn-ghost:hover:not(:disabled){background:var(--bg-hover); color:var(--fg)}

.btn-text{background:transparent; color:var(--fg-brand); padding:0 var(--s-2); height:auto}
.btn-text:hover:not(:disabled){text-decoration:underline}

.btn-danger{background:var(--err); color:var(--n-0); border-color:var(--err); box-shadow:var(--sh-xs)}
.btn-danger:hover:not(:disabled){filter:brightness(.92)}
:root[data-theme="dark"] .btn-danger{color:var(--n-25)}

/* E-02 图标按钮 / E-03 按钮组 / E-04 分裂按钮 */
.icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:var(--h-ctl); height:var(--h-ctl); padding:0; border-radius:var(--r-md);
  border:1px solid transparent; background:transparent; color:var(--fg-soft); cursor:pointer;
  transition:background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.icon-btn:hover{background:var(--bg-hover); color:var(--fg)}
.icon-btn:focus-visible{outline:none; box-shadow:var(--ring)}
.icon-btn-sm{width:var(--h-ctl-sm); height:var(--h-ctl-sm)}

.btn-group{display:inline-flex; box-shadow:var(--sh-xs); border-radius:var(--r-md)}
.btn-group .btn{border-radius:0; box-shadow:none; margin-left:-1px}
.btn-group .btn:first-child{border-radius:var(--r-md) 0 0 var(--r-md); margin-left:0}
.btn-group .btn:last-child{border-radius:0 var(--r-md) var(--r-md) 0}

/* ============ D 表单 Forms ============ */
.field{display:flex; flex-direction:column; gap:var(--s-3)}
.label{font-size:var(--t-sm); font-weight:var(--w-medium); color:var(--fg)}
.label .req{color:var(--err-fg); margin-left:2px}
.hint{font-size:var(--t-sm); color:var(--fg-faint)}
.hint.err{color:var(--err-fg)}

.input, .textarea, .select{
  width:100%; height:var(--h-ctl); padding:0 var(--s-5);
  font:inherit; font-size:var(--t-md); color:var(--fg);
  background:var(--bg-surface); border:1px solid var(--bd); border-radius:var(--r-md);
  box-shadow:var(--sh-xs);
  transition:border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.input::placeholder,.textarea::placeholder{color:var(--fg-disabled)}
.input:hover,.textarea:hover,.select:hover{border-color:var(--bd-strong)}
.input:focus,.textarea:focus,.select:focus{outline:none; border-color:var(--b-500); box-shadow:var(--ring)}
.input:disabled,.textarea:disabled,.select:disabled{background:var(--bg-sunken); color:var(--fg-disabled); cursor:not-allowed}
.input.is-err,.textarea.is-err{border-color:var(--err)}
.input.is-err:focus{box-shadow:var(--ring-err)}
.textarea{height:auto; min-height:84px; padding:var(--s-4) var(--s-5); line-height:var(--lh-md); resize:vertical}
.select{appearance:none; padding-right:var(--s-9); cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 18px) 16px, calc(100% - 13px) 16px;
  background-size:5px 5px,5px 5px; background-repeat:no-repeat}
.input-group{display:flex; align-items:center; position:relative}
.input-group .affix{position:absolute; left:var(--s-5); color:var(--fg-faint); font-size:var(--t-md); pointer-events:none}
.input-group .input{padding-left:var(--s-9)}

.check{display:inline-flex; align-items:flex-start; gap:var(--s-4); cursor:pointer; font-size:var(--t-md)}
.check input{width:16px; height:16px; margin:3px 0 0; accent-color:var(--b-500); cursor:pointer; flex:none}
.check:has(input:disabled){cursor:not-allowed; color:var(--fg-disabled)}

.switch{position:relative; display:inline-flex; align-items:center; gap:var(--s-4); cursor:pointer}
.switch input{position:absolute; opacity:0; width:0; height:0}
.switch .track{
  width:40px; height:22px; border-radius:var(--r-full); background:var(--n-300);
  position:relative; transition:background var(--dur) var(--ease); flex:none;
}
.switch .track::after{
  content:""; position:absolute; top:2px; left:2px; width:18px; height:18px;
  border-radius:var(--r-full); background:var(--n-0); box-shadow:var(--sh-sm);
  transition:transform var(--dur) var(--ease);
}
.switch input:checked + .track{background:var(--b-500)}
.switch input:checked + .track::after{transform:translateX(18px)}
.switch input:focus-visible + .track{box-shadow:var(--ring)}
.switch input:disabled + .track{opacity:.5}

.slider{-webkit-appearance:none; width:100%; height:6px; border-radius:var(--r-full); background:var(--n-200); outline:none}
.slider::-webkit-slider-thumb{-webkit-appearance:none; width:18px; height:18px; border-radius:var(--r-full);
  background:var(--n-0); border:2px solid var(--b-500); box-shadow:var(--sh-sm); cursor:pointer}

.tag-input{
  display:flex; flex-wrap:wrap; gap:var(--s-3); align-items:center; min-height:var(--h-ctl);
  padding:var(--s-3) var(--s-4); background:var(--bg-surface);
  border:1px solid var(--bd); border-radius:var(--r-md); box-shadow:var(--sh-xs);
}
.tag-input input{border:0; outline:0; background:transparent; font:inherit; font-size:var(--t-md); flex:1; min-width:80px; color:var(--fg)}

.dropzone{
  display:flex; flex-direction:column; align-items:center; gap:var(--s-4);
  padding:var(--s-9) var(--s-6); text-align:center;
  border:1px dashed var(--bd-strong); border-radius:var(--r-lg); background:var(--bg-surface);
  transition:border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.dropzone:hover{border-color:var(--b-500); background:var(--b-50)}

/* D-17 筛选栏 / D-18 批量操作条 */
.filter-bar{display:flex; flex-wrap:wrap; gap:var(--s-4); align-items:center;
  padding:var(--s-5); background:var(--bg-surface); border:1px solid var(--bd); border-radius:var(--r-lg)}
.bulk-bar{
  display:flex; align-items:center; gap:var(--s-5); padding:var(--s-4) var(--s-6);
  background:var(--bg-inverse); color:var(--fg-inverse); border-radius:var(--r-lg); box-shadow:var(--sh-lg);
}
.bulk-bar .btn-ghost{color:var(--n-300)}
.bulk-bar .btn-ghost:hover{background:rgba(255,255,255,.1); color:var(--n-0)}

/* ============ C 数据展示 Data Display ============ */
.card{
  background:var(--bg-surface); border:1px solid var(--bd);
  border-radius:var(--r-xl); box-shadow:var(--sh-sm);
}
.card-head{display:flex; align-items:flex-start; gap:var(--s-5); flex-wrap:wrap;
  padding:var(--s-6) var(--s-6) var(--s-5)}
.card-head > div{min-width:0}
.card-head h3{margin:0; font-size:var(--t-lg); font-weight:var(--w-semibold); line-height:var(--lh-lg)}
.card-head p{margin:2px 0 0; font-size:var(--t-sm); color:var(--fg-faint)}
.card-head .spacer{margin-left:auto}
/* 默认四边等距。原来写死上 padding:0，是假设一定跟在 card-head 后面——
   一旦单独用（或前面有水印等绝对定位元素），标题就贴死在上沿。改成反向声明。 */
.card-body{padding:var(--s-6)}
.card-head + .card-body{padding-top:0}
.card-foot{padding:var(--s-5) var(--s-6); border-top:1px solid var(--bd-soft); background:var(--bg-sunken);
  border-radius:0 0 var(--r-xl) var(--r-xl)}

/* C-02 指标卡 */
.stat-card{padding:var(--s-6); display:flex; flex-direction:column; gap:var(--s-4)}
.stat-card .cap{font-size:var(--t-sm); color:var(--fg-faint); font-weight:var(--w-medium)}
.stat-card .val{font-size:var(--t-d-md); line-height:var(--lh-d-md); font-weight:var(--w-semibold); letter-spacing:-.02em}
.stat-card .row{display:flex; align-items:center; gap:var(--s-4)}
.delta{display:inline-flex; align-items:center; gap:var(--s-2); font-size:var(--t-sm); font-weight:var(--w-medium);
  padding:2px var(--s-3); border-radius:var(--r-full)}
.delta.up{color:var(--ok-fg); background:var(--ok-bg)}
.delta.down{color:var(--err-fg); background:var(--err-bg)}
.delta.flat{color:var(--fg-faint); background:var(--bg-sunken)}

/* C-03 表格 */
.table-wrap{overflow-x:auto; border:1px solid var(--bd); border-radius:var(--r-xl); background:var(--bg-surface)}
table.tbl{width:100%; border-collapse:collapse; font-size:var(--t-md)}
.tbl thead th{
  text-align:left; padding:var(--s-5) var(--s-6); background:var(--bg-sunken);
  font-size:var(--t-sm); font-weight:var(--w-semibold); color:var(--fg-soft); white-space:nowrap;
  border-bottom:1px solid var(--bd);
}
.tbl tbody td{padding:var(--s-5) var(--s-6); border-bottom:1px solid var(--bd-soft); vertical-align:middle}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr:hover{background:var(--bg-hover)}
.tbl .cell-user{display:flex; align-items:center; gap:var(--s-5)}
.tbl .cell-user .nm{font-weight:var(--w-medium)}
.tbl .cell-user .sub{font-size:var(--t-sm); color:var(--fg-faint)}
.sortable{cursor:pointer; user-select:none}
.sortable::after{content:"↕"; margin-left:var(--s-3); opacity:.4; font-size:var(--t-xs)}
.sortable[aria-sort="ascending"]::after{content:"↑"; opacity:1}
.sortable[aria-sort="descending"]::after{content:"↓"; opacity:1}

/* C-16 头像 */
.avatar{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:36px; height:36px; border-radius:var(--r-full);
  background:var(--b-100); color:var(--b-700);
  font-size:var(--t-sm); font-weight:var(--w-semibold); overflow:hidden;
}
.avatar-xs{width:24px; height:24px; font-size:var(--t-xs)}
.avatar-sm{width:30px; height:30px; font-size:var(--t-xs)}
.avatar-lg{width:48px; height:48px; font-size:var(--t-lg)}
.avatar-group{display:inline-flex}
.avatar-group .avatar{border:2px solid var(--bg-surface); margin-left:-10px}
.avatar-group .avatar:first-child{margin-left:0}

/* C-17/18/19 徽标·标签·状态胶囊 */
.badge{display:inline-flex; align-items:center; justify-content:center; min-width:20px; height:20px;
  padding:0 var(--s-3); border-radius:var(--r-full); background:var(--err); color:var(--n-0);
  font-size:var(--t-xs); font-weight:var(--w-semibold)}
.badge.dot{min-width:8px; width:8px; height:8px; padding:0}

.tag{display:inline-flex; align-items:center; gap:var(--s-3); height:24px; padding:0 var(--s-4);
  border-radius:var(--r-sm); background:var(--bg-sunken); border:1px solid var(--bd);
  font-size:var(--t-sm); font-weight:var(--w-medium); color:var(--fg-soft); white-space:nowrap; flex:none}
.tag .x{cursor:pointer; opacity:.5; font-size:var(--t-md)}
.tag .x:hover{opacity:1}
.tag.brand{background:var(--b-50); border-color:var(--b-200); color:var(--b-700)}

.pill{display:inline-flex; align-items:center; gap:var(--s-3); height:24px; padding:0 var(--s-4);
  border-radius:var(--r-full); font-size:var(--t-sm); font-weight:var(--w-medium);
  border:1px solid transparent; white-space:nowrap; flex:none}
.pill::before{content:""; width:6px; height:6px; flex:none; border-radius:var(--r-full); background:currentColor}
.pill.ok{color:var(--ok-fg); background:var(--ok-bg); border-color:var(--ok-bd)}
.pill.warn{color:var(--warn-fg); background:var(--warn-bg); border-color:var(--warn-bd)}
.pill.err{color:var(--err-fg); background:var(--err-bg); border-color:var(--err-bd)}
.pill.info{color:var(--info-fg); background:var(--info-bg); border-color:var(--info-bd)}
.pill.neutral{color:var(--fg-soft); background:var(--bg-sunken); border-color:var(--bd)}

/* C-14/15 进度 */
.progress{height:8px; border-radius:var(--r-full); background:var(--n-200); overflow:hidden}
.progress > i{display:block; height:100%; border-radius:var(--r-full); background:var(--b-500);
  transition:width var(--dur-slow) var(--ease)}
.progress.ok > i{background:var(--ok)}
.progress.warn > i{background:var(--warn)}

/* C-20/21 tooltip / popover */
.tip{position:relative; display:inline-flex}
.tip .bubble{
  position:absolute; bottom:calc(100% + 8px); left:50%; transform:translateX(-50%);
  padding:var(--s-3) var(--s-4); border-radius:var(--r-sm);
  background:var(--bg-inverse); color:var(--fg-inverse);
  font-size:var(--t-sm); white-space:nowrap; box-shadow:var(--sh-md);
  opacity:0; pointer-events:none; transition:opacity var(--dur-fast) var(--ease);
}
.tip:hover .bubble, .tip:focus-within .bubble{opacity:1}
.popover{padding:var(--s-6); background:var(--bg-surface); border:1px solid var(--bd);
  border-radius:var(--r-lg); box-shadow:var(--sh-lg); max-width:280px}

/* C-22 折叠面板 */
.accordion{border:1px solid var(--bd); border-radius:var(--r-lg); background:var(--bg-surface); overflow:hidden}
.accordion details{border-bottom:1px solid var(--bd-soft)}
.accordion details:last-child{border-bottom:0}
.accordion summary{padding:var(--s-5) var(--s-6); cursor:pointer; font-weight:var(--w-medium); list-style:none;
  display:flex; align-items:center; gap:var(--s-4)}
.accordion summary::-webkit-details-marker{display:none}
.accordion summary::before{content:"›"; transition:transform var(--dur-fast) var(--ease); color:var(--fg-faint); font-size:var(--t-lg)}
.accordion details[open] summary::before{transform:rotate(90deg)}
.accordion summary:hover{background:var(--bg-hover)}
.accordion .acc-body{padding:0 var(--s-6) var(--s-6) var(--s-10); color:var(--fg-soft); font-size:var(--t-sm)}

/* C-07 时间线 / C-08 动态流 */
.timeline{display:flex; flex-direction:column; gap:0; list-style:none; margin:0; padding:0}
.timeline li{display:grid; grid-template-columns:24px 1fr; gap:var(--s-5); padding-bottom:var(--s-7); position:relative}
.timeline li::before{content:""; position:absolute; left:11px; top:20px; bottom:0; width:1px; background:var(--bd)}
.timeline li:last-child{padding-bottom:0}
.timeline li:last-child::before{display:none}
.timeline .node{width:24px; height:24px; border-radius:var(--r-full); background:var(--bg-surface);
  border:2px solid var(--bd-strong); display:flex; align-items:center; justify-content:center; font-size:var(--t-xs)}
.timeline li.done .node{background:var(--b-500); border-color:var(--b-500); color:var(--n-0)}
.timeline .tl-body strong{font-size:var(--t-md); font-weight:var(--w-medium)}
.timeline .tl-body p{margin:2px 0 0; font-size:var(--t-sm); color:var(--fg-faint)}

/* C-23 分割线 */
.divider{height:1px; background:var(--bd); border:0; margin:var(--s-6) 0}
.divider-label{display:flex; align-items:center; gap:var(--s-5); color:var(--fg-faint); font-size:var(--t-sm); margin:var(--s-6) 0}
.divider-label::before,.divider-label::after{content:""; flex:1; height:1px; background:var(--bd)}

/* ============ B 导航 Navigation ============ */
.nav-item{
  display:flex; align-items:center; gap:var(--s-5); height:40px; padding:0 var(--s-5);
  border-radius:var(--r-md); color:var(--fg-soft); font-size:var(--t-md); font-weight:var(--w-medium);
  text-decoration:none; cursor:pointer; transition:background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav-item:hover{background:var(--bg-hover); color:var(--fg)}
.nav-item[aria-current="page"]{background:var(--bg-active); color:var(--fg-brand); font-weight:var(--w-semibold)}
.nav-item .ico{width:18px; text-align:center; flex:none; opacity:.85}
.nav-item .cnt{margin-left:auto; font-size:var(--t-xs); color:var(--fg-faint); font-variant-numeric:tabular-nums}
.nav-item[aria-disabled="true"]{opacity:.45; pointer-events:none}
.nav-group{font-size:var(--t-xs); font-weight:var(--w-semibold); color:var(--fg-faint);
  letter-spacing:.08em; text-transform:uppercase; padding:var(--s-6) var(--s-5) var(--s-3)}

.tabs{display:flex; gap:var(--s-2); border-bottom:1px solid var(--bd)}
.tabs button{
  font:inherit; font-size:var(--t-md); font-weight:var(--w-medium); color:var(--fg-faint);
  background:none; border:0; padding:var(--s-4) var(--s-5); cursor:pointer;
  border-bottom:2px solid transparent; margin-bottom:-1px;
}
.tabs button:hover{color:var(--fg)}
.tabs button[aria-selected="true"]{color:var(--fg-brand); border-bottom-color:var(--b-500)}

.segmented{display:inline-flex; padding:3px; gap:2px; background:var(--bg-sunken);
  border:1px solid var(--bd); border-radius:var(--r-md)}
.segmented button{font:inherit; font-size:var(--t-sm); font-weight:var(--w-medium); color:var(--fg-soft);
  background:none; border:0; padding:var(--s-3) var(--s-5); border-radius:var(--r-sm); cursor:pointer}
.segmented button[aria-pressed="true"]{background:var(--bg-surface); color:var(--fg); box-shadow:var(--sh-xs)}
/* 放进定宽容器（如侧栏）时要撑满，否则右边空一大块 */
.segmented.is-fill{display:flex; width:100%}
.segmented.is-fill button{flex:1; text-align:center}

.breadcrumb{display:flex; align-items:center; gap:var(--s-3); font-size:var(--t-sm); color:var(--fg-faint)}
.breadcrumb a{text-decoration:none; color:var(--fg-faint)}
.breadcrumb a:hover{color:var(--fg)}
.breadcrumb .sep{opacity:.5}
.breadcrumb .cur{color:var(--fg); font-weight:var(--w-medium)}

.steps{display:flex; align-items:center; gap:var(--s-2)}
.steps .step{display:flex; align-items:center; gap:var(--s-4); font-size:var(--t-sm); color:var(--fg-faint)}
.steps .step .n{width:24px; height:24px; border-radius:var(--r-full); border:1px solid var(--bd-strong);
  display:flex; align-items:center; justify-content:center; font-size:var(--t-xs); font-weight:var(--w-semibold)}
.steps .step.done .n{background:var(--b-500); border-color:var(--b-500); color:var(--n-0)}
.steps .step.cur{color:var(--fg); font-weight:var(--w-semibold)}
.steps .step.cur .n{border-color:var(--b-500); color:var(--fg-brand)}
.steps .bar{width:36px; height:1px; background:var(--bd)}

.pagination{display:flex; align-items:center; gap:var(--s-2)}
.pagination button{min-width:32px; height:32px; padding:0 var(--s-3); border-radius:var(--r-sm);
  border:1px solid transparent; background:none; font:inherit; font-size:var(--t-sm); color:var(--fg-soft); cursor:pointer;
  font-variant-numeric:tabular-nums}
.pagination button:hover{background:var(--bg-hover)}
.pagination button[aria-current="page"]{background:var(--bg-active); color:var(--fg-brand); font-weight:var(--w-semibold)}

.menu{min-width:200px; padding:var(--s-3); background:var(--bg-surface); border:1px solid var(--bd);
  border-radius:var(--r-lg); box-shadow:var(--sh-lg)}
.menu .mi{display:flex; align-items:center; gap:var(--s-5); padding:var(--s-4) var(--s-4);
  border-radius:var(--r-sm); font-size:var(--t-md); color:var(--fg); cursor:pointer}
.menu .mi:hover{background:var(--bg-hover)}
.menu .mi.danger{color:var(--err-fg)}
.menu .mi .k{margin-left:auto; font-family:var(--font-mono); font-size:var(--t-xs); color:var(--fg-disabled)}
.menu .mg{font-size:var(--t-xs); color:var(--fg-faint); padding:var(--s-4) var(--s-4) var(--s-2);
  letter-spacing:.06em; text-transform:uppercase}
.menu hr{border:0; border-top:1px solid var(--bd-soft); margin:var(--s-3) 0}

.tree{list-style:none; margin:0; padding:0; font-size:var(--t-md)}
.tree li{padding-left:var(--s-6)}
.tree > li{padding-left:0}
.tree .ti{display:flex; align-items:center; gap:var(--s-4); padding:var(--s-3) var(--s-4);
  border-radius:var(--r-sm); cursor:pointer; color:var(--fg-soft)}
.tree .ti:hover{background:var(--bg-hover); color:var(--fg)}

/* ============ E 反馈 Feedback ============ */
.alert{display:flex; gap:var(--s-5); padding:var(--s-5) var(--s-6);
  border:1px solid var(--bd); border-radius:var(--r-lg); background:var(--bg-surface); font-size:var(--t-md)}
.alert .ai{flex:none; font-size:var(--t-lg); line-height:1.2}
.alert strong{display:block; font-weight:var(--w-semibold); margin-bottom:2px}
.alert p{margin:0; color:var(--fg-soft); font-size:var(--t-sm)}
.alert.ok{background:var(--ok-bg); border-color:var(--ok-bd)} .alert.ok .ai{color:var(--ok-fg)}
.alert.warn{background:var(--warn-bg); border-color:var(--warn-bd)} .alert.warn .ai{color:var(--warn-fg)}
.alert.err{background:var(--err-bg); border-color:var(--err-bd)} .alert.err .ai{color:var(--err-fg)}
.alert.info{background:var(--info-bg); border-color:var(--info-bd)} .alert.info .ai{color:var(--info-fg)}

.toast{display:flex; align-items:center; gap:var(--s-5); padding:var(--s-5) var(--s-6);
  background:var(--bg-inverse); color:var(--fg-inverse); border-radius:var(--r-lg);
  box-shadow:var(--sh-xl); font-size:var(--t-md); max-width:420px}
.toast .btn-text{color:var(--b-300); margin-left:auto}

.modal{width:min(520px,100%); background:var(--bg-surface); border-radius:var(--r-2xl);
  box-shadow:var(--sh-xl); border:1px solid var(--bd); overflow:hidden}
.modal-head{padding:var(--s-8) var(--s-8) var(--s-5)}
.modal-head h3{margin:0; font-size:var(--t-xl); font-weight:var(--w-semibold)}
.modal-head p{margin:var(--s-3) 0 0; color:var(--fg-soft); font-size:var(--t-md)}
.modal-body{padding:0 var(--s-8) var(--s-6)}
.modal-foot{display:flex; justify-content:flex-end; gap:var(--s-4);
  padding:var(--s-6) var(--s-8); background:var(--bg-sunken); border-top:1px solid var(--bd-soft)}

.spinner{width:20px; height:20px; border-radius:var(--r-full);
  border:2px solid var(--n-200); border-top-color:var(--b-500); animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

.skel{background:linear-gradient(90deg,var(--bg-sunken) 25%,var(--n-200) 37%,var(--bg-sunken) 63%);
  background-size:400% 100%; animation:sk 1.4s ease infinite; border-radius:var(--r-sm); height:12px}
@keyframes sk{0%{background-position:100% 50%}100%{background-position:0 50%}}

.empty{display:flex; flex-direction:column; align-items:center; gap:var(--s-5);
  padding:var(--s-11) var(--s-8); text-align:center}
.empty .glyph{width:48px; height:48px; border-radius:var(--r-xl); background:var(--bg-sunken);
  border:1px solid var(--bd); display:flex; align-items:center; justify-content:center; font-size:var(--t-xl)}
.empty h4{margin:0; font-size:var(--t-lg); font-weight:var(--w-semibold)}
.empty p{margin:0; max-width:44ch; color:var(--fg-faint); font-size:var(--t-sm)}

/* ============ G AI 原生（自定义，非 chatbox） ============ */
.ai-suggest{
  display:flex; gap:var(--s-5); padding:var(--s-5) var(--s-6);
  background:var(--b-50); border:1px solid var(--b-200);
  border-left:3px solid var(--b-500); border-radius:var(--r-md);
}
.ai-suggest .mark{flex:none; color:var(--b-600); font-size:var(--t-md); line-height:var(--lh-md)}
.ai-suggest .sg-body{flex:1; min-width:0}
.ai-suggest .basis{display:block; margin-top:var(--s-3); font-size:var(--t-sm); color:var(--fg-faint)}
.ai-suggest .acts{display:flex; gap:var(--s-3); margin-top:var(--s-4)}
/* 扁平状态点。原来是带高光的拟物球，和「沉静的密集界面」不是一路东西。
   现在与 .pill / .dots 同语言：实心点 + 一圈淡晕，工作时呼吸。 */
.ai-orb{width:8px; height:8px; border-radius:var(--r-full); flex:none; background:var(--b-500);
  box-shadow:0 0 0 3px color-mix(in oklab, var(--b-500) 16%, transparent);
  animation:orb 2s var(--ease) infinite}
@keyframes orb{0%,100%{box-shadow:0 0 0 3px color-mix(in oklab, var(--b-500) 16%, transparent)}
  50%{box-shadow:0 0 0 5px color-mix(in oklab, var(--b-500) 8%, transparent)}}
@media (prefers-reduced-motion:reduce){.ai-orb{animation:none}}
.ai-status{display:inline-flex; align-items:center; gap:var(--s-4); font-size:var(--t-sm); color:var(--fg-soft)}
.ai-status .dots i{display:inline-block; width:5px; height:5px; margin-right:3px; border-radius:var(--r-full);
  background:var(--b-500); animation:blink 1.2s infinite}
.ai-status .dots i:nth-child(2){animation-delay:.2s}
.ai-status .dots i:nth-child(3){animation-delay:.4s}
@keyframes blink{0%,60%,100%{opacity:.25}30%{opacity:1}}

.cite{display:inline-flex; align-items:center; gap:var(--s-2); height:20px; padding:0 var(--s-3);
  border-radius:var(--r-sm); background:var(--info-bg); border:1px solid var(--info-bd);
  color:var(--info-fg); font-size:var(--t-xs); font-weight:var(--w-medium); cursor:pointer; vertical-align:1px}

.diff{font-family:var(--font-serif); font-size:var(--t-lg); line-height:1.9}
.diff del{background:var(--err-bg); color:var(--err-fg); text-decoration:line-through; text-decoration-thickness:1px; padding:1px 2px}
.diff ins{background:var(--ok-bg); color:var(--ok-fg); text-decoration:none; padding:1px 2px; border-radius:2px}

.composer{display:flex; flex-direction:column; gap:var(--s-4); padding:var(--s-5);
  background:var(--bg-surface); border:1px solid var(--bd); border-radius:var(--r-lg); box-shadow:var(--sh-sm)}
.composer:focus-within{border-color:var(--b-500); box-shadow:var(--ring)}
.composer textarea{border:0; outline:0; resize:none; background:transparent; font:inherit;
  font-size:var(--t-md); color:var(--fg); min-height:44px}
.composer .cbar{display:flex; align-items:center; gap:var(--s-3)}
.composer .cbar .spacer{margin-left:auto}

.task-row{display:flex; align-items:center; gap:var(--s-5); padding:var(--s-5) var(--s-6);
  border-bottom:1px solid var(--bd-soft)}
.task-row:last-child{border-bottom:0}
.task-row .tr-body{flex:1; min-width:0}
.task-row .tr-body strong{font-size:var(--t-md); font-weight:var(--w-medium); display:block}
.task-row .tr-body .progress{margin-top:var(--s-3)}

.sel-toolbar{display:inline-flex; align-items:center; gap:var(--s-2); padding:var(--s-2);
  background:var(--bg-inverse); border-radius:var(--r-md); box-shadow:var(--sh-lg)}
.sel-toolbar button{font:inherit; font-size:var(--t-sm); color:var(--n-200); background:none; border:0;
  padding:var(--s-3) var(--s-4); border-radius:var(--r-sm); cursor:pointer; white-space:nowrap}
.sel-toolbar button:hover{background:rgba(255,255,255,.12); color:var(--n-0)}

/* ============ H 工作对象 Work Object ============ */
.canvas-doc{background:var(--bg-surface); border:1px solid var(--bd); border-radius:var(--r-xl);
  padding:var(--s-9); font-family:var(--font-serif); font-size:var(--t-lg); line-height:1.95; color:var(--fg)}
.canvas-doc h4{font-family:var(--font-sans); font-size:var(--t-lg); font-weight:var(--w-semibold); margin:0 0 var(--s-6)}
.canvas-doc p{margin:0 0 var(--s-6)}
.canvas-doc mark{background:var(--warn-bg); color:inherit; padding:1px 3px; border-radius:2px;
  box-shadow:inset 0 -1px 0 var(--warn-bd); cursor:pointer}

.block{position:relative; padding:var(--s-3) var(--s-4); border-radius:var(--r-sm); margin-left:calc(-1 * var(--s-4))}
.block:hover{background:var(--bg-hover)}
.block .handle{position:absolute; left:calc(-1 * var(--s-7)); top:var(--s-4); opacity:0;
  color:var(--fg-disabled); cursor:grab; font-size:var(--t-md); transition:opacity var(--dur-fast) var(--ease)}
.block:hover .handle{opacity:1}

.rubric{display:flex; flex-direction:column; gap:var(--s-5)}
.rubric-item{display:grid; grid-template-columns:1fr 44px; gap:var(--s-3) var(--s-5); align-items:center}
.rubric-item .rn{font-size:var(--t-md); font-weight:var(--w-medium)}
.rubric-item .rs{font-family:var(--font-mono); font-size:var(--t-md); text-align:right; font-variant-numeric:tabular-nums}
.rubric-item .progress{grid-column:1 / -1}

/* ============ A 骨架 Shell ============ */
.shell{display:grid; grid-template-columns:var(--w-sidebar) 1fr; min-height:520px;
  border:1px solid var(--bd); border-radius:var(--r-xl); overflow:hidden; background:var(--bg-app)}
.shell-side{background:var(--bg-surface); border-right:1px solid var(--bd);
  padding:var(--s-5); display:flex; flex-direction:column; gap:var(--s-2)}
.shell-brand{display:flex; align-items:center; gap:var(--s-5); padding:var(--s-4) var(--s-5) var(--s-6)}
.shell-brand .bm{width:32px; height:32px; border-radius:var(--r-md); background:var(--b-500); color:var(--n-0);
  display:flex; align-items:center; justify-content:center; font-weight:var(--w-bold); font-size:var(--t-md); flex:none}
.shell-brand b{font-size:var(--t-md); font-weight:var(--w-semibold); display:block; line-height:1.3}
.shell-brand span{font-size:var(--t-xs); color:var(--fg-faint)}
.shell-main{display:flex; flex-direction:column; min-width:0}
.shell-top{display:flex; align-items:center; gap:var(--s-4); min-height:var(--h-topbar);
  padding:var(--s-3) var(--s-7); background:var(--bg-surface);
  border-bottom:1px solid var(--bd); flex:none; flex-wrap:wrap}
.shell-top .spacer{margin-left:auto}
.shell-body{padding:var(--s-7); overflow:auto; flex:1; display:flex; flex-direction:column; gap:var(--s-7)}

.page-head{display:flex; align-items:flex-start; gap:var(--s-6); flex-wrap:wrap}
.page-head h2{margin:var(--s-3) 0 0; font-size:var(--t-d-sm); line-height:var(--lh-d-sm);
  font-weight:var(--w-semibold); letter-spacing:-.015em}
.page-head p{margin:var(--s-2) 0 0; color:var(--fg-faint); font-size:var(--t-sm)}
.page-head .acts{margin-left:auto; display:flex; gap:var(--s-4); align-items:center}

/* 按容器宽度自适应，不用视口断点 —— 组件常被放进比视口窄得多的容器里 */
.grid{display:grid; gap:var(--s-6)}
.g-2{grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr))}
.g-3{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr))}
.g-4{grid-template-columns:repeat(auto-fit,minmax(min(100%,196px),1fr))}

/* ============================================================
   I · 表面与质感 Surface & Texture
   决定界面「素不素」的一层。四种叠法，可组合，永远垫在内容之下。
   ============================================================ */

/* I-01 品牌水印：符号放大到容器高的 1.4–2.2 倍，裁切在角上 */
.surface-mark{position:relative; overflow:hidden; isolation:isolate}
.surface-mark>.mark{
  position:absolute; right:-.14em; bottom:-.34em; z-index:0; pointer-events:none;
  font-size:var(--mark-size,150px); line-height:.78; font-weight:var(--w-bold);
  color:var(--tex-ink); opacity:var(--mark-op,var(--tex-mark)); user-select:none;
}
.surface-mark>*:not(.mark){position:relative; z-index:1}

/* I-02 纹样底纹：由品牌符号衍生的可平铺单元，48–96px */
.surface-pattern{position:relative; isolation:isolate}
.surface-pattern::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none; border-radius:inherit;
  background-image:
    radial-gradient(circle at 12px 12px, var(--tex-ink) 1.2px, transparent 1.2px),
    radial-gradient(circle at 36px 36px, var(--tex-ink) 1.2px, transparent 1.2px);
  background-size:48px 48px; opacity:.10;
}
.surface-pattern>*{position:relative; z-index:1}

/* I-03 氛围渐变：半径取容器宽 60–90%，彩度压到品牌色的三成 */
.surface-ambient{position:relative; isolation:isolate}
.surface-ambient::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none; border-radius:inherit;
  /* 两条规则，违反任何一条都会变丑：
     ① 只用一个色相族（品牌 + 墨），绝不掺第三个色相 —— 掺了必发浑；
     ② 焦点放在容器外（100% 0% / 0% 100%），只让人看见衰减，看不见「球」。 */
  background:
    radial-gradient(120% 105% at 100% 0%,  color-mix(in oklab, var(--b-500) 8%, transparent), transparent 56%),
    radial-gradient(100% 90% at 0% 100%,   color-mix(in oklab, var(--tex-ink) 6%, transparent), transparent 60%);
}
.surface-ambient>*{position:relative; z-index:1}

/* I-04 光晕：单点柔光，用来暗示焦点而不是装饰 */
.surface-glow{position:relative; isolation:isolate; overflow:hidden}  /* ::before 左右外扩 30%，不裁会撑破文档 */
.surface-glow::before{
  content:""; position:absolute; z-index:0; pointer-events:none;
  inset:auto -30% -78% -30%; height:88%;
  background:radial-gradient(50% 100% at 50% 100%, color-mix(in oklab, var(--b-500) 14%, transparent), transparent 66%);
  filter:blur(36px);
}
.surface-glow>*{position:relative; z-index:1}

/* I-05 颗粒噪点：opacity .02–.04，soft-light 叠加，消掉大色块的塑料感 */
.surface-grain{position:relative; isolation:isolate}
.surface-grain::after{
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none; border-radius:inherit;
  opacity:var(--grain-op,var(--tex-grain)); mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* I-06 毛玻璃：浮层与侧栏，永远要有 fallback 底色 */
.surface-glass{
  background:color-mix(in oklab, var(--bg-surface) 72%, transparent);
  backdrop-filter:blur(16px) saturate(1.4); -webkit-backdrop-filter:blur(16px) saturate(1.4);
  border:1px solid color-mix(in oklab, var(--bd) 70%, transparent);
}
@supports not (backdrop-filter:blur(1px)){.surface-glass{background:var(--bg-surface)}}

/* I-10 渐变描边：用描边而非填充做强调 */
.surface-gradborder{
  border:1px solid transparent; border-radius:var(--r-lg);
  background:
    linear-gradient(var(--bg-surface),var(--bg-surface)) padding-box,
    /* 同色相内做明度差，不跨色相 */
    linear-gradient(150deg, var(--b-500), color-mix(in oklab, var(--b-500) 14%, transparent)) border-box;
}

/* I-13 分区背景：交替底色划分页面段落 */
.surface-band{background:var(--bg-sunken); border-block:1px solid var(--bd-soft)}

/* 质感样例卡 */
.tex-tile{height:186px; border-radius:var(--r-lg); border:1px solid var(--bd);
  background:var(--bg-surface); padding:var(--s-5); display:flex; flex-direction:column; justify-content:flex-end}
.tex-tile b{font-size:var(--t-sm); font-weight:var(--w-semibold)}
.tex-tile span{font-family:var(--font-mono); font-size:10px; color:var(--fg-faint); margin-top:2px}

/* ============================================================
   J · 对话 Chat & Conversation
   少用，但规格不能缺。默认贴边停靠，不做浮窗。
   ============================================================ */
.chat{display:flex; flex-direction:column; gap:var(--s-5); background:var(--bg-surface);
  border:1px solid var(--bd); border-radius:var(--r-xl); padding:var(--s-6)}
.msg{display:flex; gap:var(--s-4); align-items:flex-start}
.msg .bub{padding:var(--s-4) var(--s-5); border-radius:var(--r-lg); font-size:var(--t-md);
  line-height:var(--lh-md); max-width:min(46ch,88%)}
.msg-user{flex-direction:row-reverse}
.msg-user .bub{background:var(--b-500); color:var(--fg-inverse); border-bottom-right-radius:var(--r-xs)}
.msg-ai .bub{background:var(--bg-sunken); color:var(--fg); border-bottom-left-radius:var(--r-xs)}
.msg .meta{font-family:var(--font-mono); font-size:10px; color:var(--fg-faint); margin-top:var(--s-3)}
.msg-acts{display:flex; gap:var(--s-2); margin-top:var(--s-3); opacity:0; transition:opacity var(--dur) var(--ease)}
.msg:hover .msg-acts, .msg:focus-within .msg-acts{opacity:1}

.typing{display:inline-flex; gap:4px; align-items:center; padding:var(--s-4) var(--s-5);
  background:var(--bg-sunken); border-radius:var(--r-lg); border-bottom-left-radius:var(--r-xs)}
.typing i{width:6px; height:6px; border-radius:var(--r-full); background:var(--fg-faint);
  animation:tp 1.25s var(--ease) infinite}
.typing i:nth-child(2){animation-delay:.16s} .typing i:nth-child(3){animation-delay:.32s}
@keyframes tp{0%,60%,100%{opacity:.3; transform:translateY(0)}30%{opacity:1; transform:translateY(-3px)}}
@media (prefers-reduced-motion:reduce){.typing i{animation:none; opacity:.55}}

.composer{display:flex; gap:var(--s-4); align-items:flex-end; padding:var(--s-4);
  border:1px solid var(--bd); border-radius:var(--r-lg); background:var(--bg-surface)}
.composer:focus-within{border-color:var(--bd-brand); box-shadow:var(--ring)}
.composer textarea{flex:1; border:0; background:transparent; resize:none; font:inherit;
  font-size:var(--t-md); line-height:var(--lh-md); color:var(--fg); outline:0; min-height:44px}
.prompt-chips{display:flex; gap:var(--s-3); flex-wrap:wrap}
.prompt-chip{font:inherit; font-size:var(--t-sm); padding:var(--s-3) var(--s-5); cursor:pointer;
  border:1px solid var(--bd); border-radius:var(--r-full); background:var(--bg-surface); color:var(--fg-soft)}
.prompt-chip:hover{border-color:var(--bd-brand); color:var(--fg-brand); background:var(--bg-active)}

/* J-08 工具调用卡 · J-09 思维过程 */
.toolcall{border:1px solid var(--bd); border-radius:var(--r-md); background:var(--bg-sunken);
  padding:var(--s-4) var(--s-5); font-size:var(--t-sm)}
.toolcall .th{display:flex; gap:var(--s-4); align-items:center; font-family:var(--font-mono); font-size:var(--t-xs)}
.toolcall .th b{color:var(--fg-brand); font-weight:var(--w-semibold)}
.toolcall pre{margin:var(--s-4) 0 0; font-family:var(--font-mono); font-size:var(--t-xs);
  color:var(--fg-faint); white-space:pre-wrap; overflow-x:auto}
.reasoning{border-left:2px solid var(--bd-strong); padding:var(--s-2) 0 var(--s-2) var(--s-5);
  color:var(--fg-faint); font-size:var(--t-sm); line-height:var(--lh-sm)}
.reasoning summary{cursor:pointer; color:var(--fg-soft); font-size:var(--t-xs);
  font-family:var(--font-mono); margin-bottom:var(--s-3)}

/* ============================================================
   G 补 · 沉浸式修改 Immersive Editing
   ============================================================ */
.diff ins{background:var(--ok-bg); color:var(--ok-fg); text-decoration:none;
  padding:1px 3px; border-radius:3px; box-shadow:inset 0 -1px 0 var(--ok-bd)}
.diff del{background:var(--err-bg); color:var(--err-fg); text-decoration:line-through;
  padding:1px 3px; border-radius:3px; opacity:.8}
.diff-split{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));
  gap:1px; background:var(--bd); border:1px solid var(--bd); border-radius:var(--r-lg); overflow:hidden}
.diff-split>div{background:var(--bg-surface); padding:var(--s-5)}
.diff-split .dh{font-family:var(--font-mono); font-size:var(--t-xs); color:var(--fg-faint);
  margin-bottom:var(--s-4); text-transform:uppercase; letter-spacing:.08em}

.versions{display:flex; flex-direction:column; gap:0}
.ver{display:flex; gap:var(--s-5); align-items:flex-start; padding:var(--s-4) 0;
  border-bottom:1px solid var(--bd-soft); font-size:var(--t-sm)}
.ver:last-child{border-bottom:0}
.ver .dot{width:8px; height:8px; border-radius:var(--r-full); background:var(--bd-strong); margin-top:6px; flex:none}
.ver[aria-current="true"] .dot{background:var(--b-500); box-shadow:0 0 0 3px var(--bg-active)}
.ver .vt{font-family:var(--font-mono); font-size:var(--t-xs); color:var(--fg-faint); margin-left:auto; flex:none}

.thread{border:1px solid var(--bd); border-radius:var(--r-lg); background:var(--bg-surface); padding:var(--s-5)}
.thread .cm{display:flex; gap:var(--s-4); padding:var(--s-4) 0; border-bottom:1px solid var(--bd-soft)}
.thread .cm:last-of-type{border-bottom:0}
.thread .cm p{margin:var(--s-2) 0 0; font-size:var(--t-sm); line-height:var(--lh-sm); color:var(--fg-soft)}
.presence{display:flex; align-items:center; gap:var(--s-3)}
.presence .stack{display:flex}
.presence .stack .avatar{margin-left:-8px; box-shadow:0 0 0 2px var(--bg-surface)}
.presence .stack .avatar:first-child{margin-left:0}
.caret{position:relative; display:inline-block; width:2px; height:16px; background:var(--info); vertical-align:-3px}
.caret::after{content:attr(data-who); position:absolute; top:-16px; left:0; white-space:nowrap;
  background:var(--info); color:#fff; font-size:9px; padding:1px 4px; border-radius:3px 3px 3px 0}

/* ============================================================
   K · 交互与状态 Interaction & States
   ============================================================ */
kbd{font-family:var(--font-mono); font-size:var(--t-xs); line-height:1; padding:3px 6px;
  border:1px solid var(--bd-strong); border-bottom-width:2px; border-radius:var(--r-xs);
  background:var(--bg-surface); color:var(--fg-soft)}
.state-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,124px),1fr)); gap:var(--s-5)}
.state-cell{display:flex; flex-direction:column; gap:var(--s-3); align-items:flex-start}
.state-cell .sl{font-family:var(--font-mono); font-size:10px; color:var(--fg-faint)}
.motion-row{display:flex; gap:var(--s-5); align-items:center; padding:var(--s-4) 0;
  border-bottom:1px solid var(--bd-soft); font-size:var(--t-sm)}
.motion-row:last-child{border-bottom:0}
.motion-row .track{flex:1; height:3px; background:var(--bg-sunken); border-radius:var(--r-full); position:relative; min-width:80px}
.motion-row .track i{position:absolute; inset-block:-3px; width:9px; height:9px; border-radius:var(--r-full);
  background:var(--b-500); animation:slide 2.4s infinite}
@keyframes slide{0%,8%{left:0}50%,58%{left:calc(100% - 9px)}100%{left:0}}
@media (prefers-reduced-motion:reduce){.motion-row .track i{animation:none}}
.dragrow{display:flex; align-items:center; gap:var(--s-4); padding:var(--s-4) var(--s-5);
  border:1px solid var(--bd); border-radius:var(--r-md); background:var(--bg-surface); font-size:var(--t-sm)}
.dragrow.is-ghost{opacity:.45; border-style:dashed}
.dragrow .grip{cursor:grab; color:var(--fg-disabled); font-size:14px; line-height:1}
.droptarget{height:2px; background:var(--b-500); border-radius:var(--r-full); position:relative}
.droptarget::before{content:""; position:absolute; left:-4px; top:-3px; width:8px; height:8px;
  border-radius:var(--r-full); background:var(--b-500)}

/* ============================================================
   L · 教学专用 Teaching-specific
   ============================================================ */
.qcard{border:1px solid var(--bd); border-radius:var(--r-lg); background:var(--bg-surface); overflow:hidden}
.qcard .qh{display:flex; gap:var(--s-4); align-items:center; padding:var(--s-5);
  border-bottom:1px solid var(--bd-soft); background:var(--bg-sunken)}
.qcard .qb{padding:var(--s-5)}
.qcard .stem{margin:0 0 var(--s-5); font-size:var(--t-md); line-height:var(--lh-lg)}
.opt{display:flex; gap:var(--s-4); align-items:flex-start; padding:var(--s-4) var(--s-5);
  border:1px solid var(--bd); border-radius:var(--r-md); margin-bottom:var(--s-3);
  font-size:var(--t-sm); cursor:pointer; background:var(--bg-surface)}
.opt:hover{border-color:var(--bd-strong); background:var(--bg-hover)}
.opt .k{font-family:var(--font-mono); font-weight:var(--w-semibold); color:var(--fg-faint); flex:none}
.opt.is-right{border-color:var(--ok-bd); background:var(--ok-bg)} .opt.is-right .k{color:var(--ok-fg)}
.opt.is-wrong{border-color:var(--err-bd); background:var(--err-bg)} .opt.is-wrong .k{color:var(--err-fg)}

.player{border:1px solid var(--bd); border-radius:var(--r-lg); background:var(--bg-surface); overflow:hidden}
.player .stage{aspect-ratio:16/7; background:var(--n-900); display:grid; place-items:center;
  color:var(--n-400); font-size:var(--t-sm)}
.player .bar{display:flex; align-items:center; gap:var(--s-4); padding:var(--s-4) var(--s-5)}
.player .seek{flex:1; height:4px; border-radius:var(--r-full); background:var(--bg-sunken); position:relative}
.player .seek i{position:absolute; inset-block:0; left:0; width:38%; border-radius:var(--r-full); background:var(--b-500)}
.player .tc{font-family:var(--font-mono); font-size:var(--t-xs); color:var(--fg-faint); font-variant-numeric:tabular-nums}
.wave{display:flex; align-items:center; gap:2px; height:32px}
.wave i{width:3px; border-radius:var(--r-full); background:var(--b-400)}

/* ============================================================
   配色方案选择器：必须自带预览，光有名字选不动
   色值写死是故意的 —— 它展示的是「另一套配色」，不能跟着当前主题变
   ============================================================ */
.palettes{display:flex; flex-direction:column; gap:var(--s-3)}
.palettes button{
  display:flex; align-items:center; gap:var(--s-4); width:100%; cursor:pointer;
  padding:var(--s-3) var(--s-4); font:inherit; font-size:var(--t-xs); color:var(--fg-soft);
  border:1px solid var(--bd); border-radius:var(--r-md); background:var(--bg-surface);
  transition:border-color var(--dur-fast) var(--ease);
}
.palettes button:hover{border-color:var(--bd-strong); color:var(--fg)}
.palettes button[aria-pressed="true"]{border-color:var(--fg); color:var(--fg); font-weight:var(--w-medium)}
.palettes .pv{display:flex; flex:none; width:44px; height:16px; border-radius:3px; overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.10)}
.palettes .pv i{flex:1}
.palettes .tick{margin-left:auto; opacity:0; font-size:11px}
.palettes button[aria-pressed="true"] .tick{opacity:1}

/* ============================================================
   文档站页头的品牌水印：黑为主，红只作一道细线
   ============================================================ */
.ds-h{position:relative; isolation:isolate; overflow:hidden}
.ds-h>*{position:relative; z-index:1}
.ds-h::before{
  content:"华"; position:absolute; z-index:0; right:-.05em; top:50%; translate:0 -52%;
  font-size:clamp(150px,20vw,260px); line-height:.8; font-weight:var(--w-bold);
  color:var(--tex-ink); opacity:calc(var(--tex-mark) * .9); pointer-events:none; user-select:none;
}
.ds-h .rule{position:absolute; z-index:1; left:0; top:0; width:34px; height:2px; background:var(--b-500)}

/* ============================================================
   导航面（侧栏）走 --bg-nav 槽位
   云杉与所有深色档下这些 token 指回原值，观感不变；
   华云浅色档把它整块压成近黑 —— 黑红配色的浅色版靠这块黑立住。
   ============================================================ */
.ds-side, .shell-side{background:var(--bg-nav); border-right-color:var(--bd-nav)}
.ds-side .nav-item, .shell-side .nav-item{color:var(--fg-nav)}
.ds-side .nav-item:hover, .shell-side .nav-item:hover{background:var(--bg-nav-hover); color:var(--fg-nav-strong)}
.ds-side .nav-item[aria-current="page"], .shell-side .nav-item[aria-current="page"]{
  background:var(--bg-nav-active); color:var(--fg-nav-active)}
.ds-side .nav-group, .shell-side .nav-group{color:var(--fg-nav-faint)}
.ds-side .shell-brand b, .shell-side .shell-brand b{color:var(--fg-nav-strong)}
.ds-side .shell-brand span, .shell-side .shell-brand span{color:var(--fg-nav-faint)}
.ds-side .nav-item .cnt, .shell-side .nav-item .cnt{
  background:color-mix(in oklab, var(--fg-nav-strong) 14%, transparent); color:var(--fg-nav-strong)}

/* 侧栏底部的两个选择器坐在深色面上，要跟着翻 */
.ds-side .themebar .segmented{background:color-mix(in oklab, var(--fg-nav-strong) 8%, transparent);
  border-color:var(--bd-nav)}
.ds-side .themebar .segmented button{color:var(--fg-nav)}
.ds-side .themebar .segmented button[aria-pressed="true"]{
  background:var(--bg-nav-active); color:var(--fg-nav-active); box-shadow:none}
.ds-side .palettes button{background:color-mix(in oklab, var(--fg-nav-strong) 6%, transparent);
  border-color:var(--bd-nav); color:var(--fg-nav)}
.ds-side .palettes button:hover{background:var(--bg-nav-hover); border-color:var(--bg-nav-hover); color:var(--fg-nav-strong)}
.ds-side .palettes button[aria-pressed="true"]{border-color:var(--fg-nav-strong); color:var(--fg-nav-strong)}

/* 黑色细线条：章节标题下压一道近黑实线，浅色版的骨架感来自这里 */
.sec-h{border-bottom:2px solid var(--fg); padding-bottom:var(--s-5)}

/* ============================================================
   药丸开关 Pill Toggle —— 两态互斥、体积最小的切换件
   ============================================================ */
.pill-toggle{display:inline-flex; align-items:center; gap:2px; padding:3px; flex:none;
  border-radius:var(--r-full); background:color-mix(in oklab, var(--fg-nav-strong) 9%, transparent);
  border:1px solid var(--bd-nav)}
.pill-toggle button{
  width:28px; height:22px; display:grid; place-items:center; font:inherit; font-size:12px; line-height:1;
  border:0; border-radius:var(--r-full); background:none; color:var(--fg-nav-faint); cursor:pointer;
  transition:background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.pill-toggle button:hover{color:var(--fg-nav-strong)}
.pill-toggle button[aria-pressed="true"]{background:var(--bg-nav-active); color:var(--fg-nav-active)}

/* ============================================================
   浮动主题按钮 —— 控页面明暗，不占版面
   ============================================================ */
.fab{
  position:fixed; right:var(--s-8); bottom:var(--s-8); z-index:60;
  display:inline-flex; align-items:center; gap:var(--s-4); cursor:pointer;
  height:var(--h-ctl-lg); padding:0 var(--s-6); border-radius:var(--r-full);
  border:1px solid var(--bd); background:var(--bg-surface); color:var(--fg-soft);
  box-shadow:var(--sh-lg); font:inherit; font-size:var(--t-sm); font-weight:var(--w-medium);
  transition:background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease);
}
.fab:hover{background:var(--bg-hover); color:var(--fg); border-color:var(--bd-strong)}
.fab:focus-visible{outline:0; box-shadow:var(--sh-lg), var(--ring)}
.fab .ico{font-size:14px; line-height:1}
@media (max-width:900px){.fab{right:var(--s-6); bottom:var(--s-6)}}

/* ============================================================
   A-02 侧边栏：顶部内圆角 + 可拖拽宽度
   ============================================================ */
/* 导航面与内容面直接相接，不做圆角衔接 —— 试过内容区左上圆角，观感突兀，撤回。 */
.shell{background:var(--bg-nav); overflow:hidden}
.shell-main{background:var(--bg-app)}

/* 拖拽调宽。手柄本体只有 5px，热区靠 ::before 撑到 11px —— 
   命中区域要比看得见的线宽，否则很难抓住。 */
.side-resizer{
  position:fixed; top:0; left:calc(var(--w-side,248px) - 2px); z-index:55;
  width:5px; height:100vh; cursor:col-resize; background:transparent;
  transition:background var(--dur-fast) var(--ease);
}
.side-resizer::before{content:""; position:absolute; inset:0 -3px}
.side-resizer:hover, .side-resizer.is-dragging{background:var(--b-500)}
.side-resizer:focus-visible{outline:0; background:var(--b-500); box-shadow:var(--ring)}
body.is-resizing{cursor:col-resize; user-select:none}
body.is-resizing iframe{pointer-events:none}
@media (max-width:900px){.side-resizer{display:none}}
