/* 基础：重置与正文排版、线条图标与图标动效、通用控件（按钮、输入框、卡片、标签、下拉菜单）、弹窗（含查看窗口、任务详情）、提示条、过渡动效 */
*{box-sizing:border-box}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
input:focus-visible,textarea:focus-visible,select:focus-visible{outline-offset:0}
/* 竖向（窄或高）窗口用底栏布局，不只是手机；滚动条轨道一直占位：各页高矮不同，有的有滚动条有的没有，页面宽度会差十几像素，底栏和内容位置就跟着跳 */
html{overflow-y:scroll;scrollbar-gutter:stable}
/* 任何一条长网址、长代码都不许把页面撑宽（手机会因此整页缩小） */
body{overflow-x:clip}
.card,.mcard,#view{min-width:0;overflow-wrap:anywhere}
body{margin:0;background:var(--bg);color:var(--text);font:var(--text-body)/var(--lh-body) var(--font-sans)}
.btn.quiet{border-color:transparent;background:none;color:var(--muted);padding:var(--sp-3) var(--sp-4)}
.btn.quiet:hover{color:var(--bad);border-color:transparent}
/* 查看窗口：对话附件、文件夹、资料库共用 */
.vbox{max-width:min(1000px,100%);height:min(88vh,100%);display:flex;flex-direction:column;overflow:hidden}
.vhead{gap:var(--sp-4);flex:none;padding-bottom:var(--sp-5);border-bottom:1px solid var(--line)}
.vname{min-width:0;flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-flex;gap:var(--sp-3);align-items:center}
.vbody{flex:1;min-height:0;overflow:auto;margin-top:var(--sp-5);display:flex;flex-direction:column;align-items:center}
.vmedia{max-width:100%;max-height:100%;object-fit:contain;margin:auto;border-radius:var(--radius-md)}video.vmedia{max-height:70vh;background:var(--media-bg)}
.vpdf{width:100%;flex:1;border:0;min-height:60vh;background:var(--doc-bg);border-radius:var(--radius-md)}
.vtext{width:100%;margin:0;white-space:pre-wrap;word-break:break-word;font-size:var(--text-small)}
.vbody .empty{margin:auto}
.i{width:1.2em;height:1.2em;vertical-align:-.22em;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;overflow:visible}
.i *{transform-box:fill-box;transform-origin:center}
.i .m-spin{transform-box:view-box;transform-origin:12px 12px}
.i .m-grow{transform-origin:50% 100%}
.i .m-draw{stroke-dasharray:1;stroke-dashoffset:0}
.i.r90{transform:rotate(90deg)}
.i.r180{transform:rotate(180deg)}
@keyframes ic-bounce{40%{transform:translateY(-2.4px)}70%{transform:translateY(.6px)}}
@keyframes ic-wiggle{20%{transform:rotate(-14deg)}50%{transform:rotate(11deg)}80%{transform:rotate(-5deg)}}
@keyframes ic-spin{to{transform:rotate(360deg)}}
@keyframes ic-pop{45%{transform:scale(1.3)}}
@keyframes ic-draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
@keyframes ic-blink{50%{opacity:.25}}
@keyframes ic-grow{from{transform:scaleY(.35)}}
@keyframes ic-slide{50%{transform:translateX(2.4px)}}
@keyframes ic-slidel{50%{transform:translateX(-2.4px)}}
@keyframes ic-pulse{50%{transform:scale(1.18)}}
@keyframes ic-quarter{to{transform:rotate(90deg)}}
/* 写字：小横条拉长 → 向上淡出 → 原位重新冒出一行；用 stroke-dasharray 拉长（pathLength=1，静态时 .3 即原来的短条），线头不会被压扁 */
.i .m-write{stroke-dasharray:.3 1}
@keyframes ic-write{0%{stroke-dasharray:.3 1;transform:none;opacity:1}40%{stroke-dasharray:1 1;transform:none;opacity:1}
  70%{stroke-dasharray:1 1;transform:translateY(-3px);opacity:0}71%{stroke-dasharray:.3 1;transform:none;opacity:0}100%{stroke-dasharray:.3 1;transform:none;opacity:1}}
.btn .i,.drop .menu button .i{margin-right:var(--sp-2);vertical-align:-.25em}
.chk .i{width:13px;height:13px;vertical-align:0}
.linkbtn .i{vertical-align:-.25em}
.gear .i{width:17px;height:17px}
.ev .i{margin-right:var(--sp-3);color:var(--muted);vertical-align:-.25em}
.grow{flex:1}
.pet{display:inline-block;width:var(--s,48px);height:var(--s,48px);flex:none;vertical-align:middle;position:relative}
.pet-host{display:block;width:100%;height:100%;cursor:pointer;-webkit-tap-highlight-color:transparent}
button.btn{border:1px solid var(--line);background:var(--panel);color:var(--text);padding:var(--sp-3) var(--sp-7);border-radius:var(--r-btn);min-height:var(--control-h);cursor:pointer;font:inherit}
button.btn:hover{border-color:var(--accent)}
button.primary{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
button.danger{color:var(--bad)}
input,textarea,select{width:100%;border:1px solid var(--line);background:var(--panel);color:var(--text);border-radius:var(--r-btn);padding:var(--sp-4) var(--sp-5);font:inherit}
textarea{resize:vertical}
.modelpick{position:absolute;left:0;right:0;top:100%;z-index:var(--z-float);max-height:260px;overflow:auto;margin-top:var(--sp-2);background:var(--panel);border:1px solid var(--line);border-radius:var(--r-btn);box-shadow:var(--shadow-dialog)}
.modelpick button{display:block;width:100%;text-align:left;border:0;background:none;color:var(--text);padding:7px var(--sp-5);font:inherit;cursor:pointer}
.modelpick button:hover{background:color-mix(in srgb,var(--text) 9%,transparent)}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-7) var(--sp-8);margin-bottom:var(--sp-5)}
.row{display:flex;gap:var(--sp-4);align-items:center;flex-wrap:wrap}
.muted{color:var(--muted);font-size:var(--text-caption)}
.tag{font-size:var(--text-micro);padding:1px var(--sp-4);border-radius:var(--radius-pill);background:var(--line);color:var(--muted);white-space:nowrap}
.st-pending{background:var(--accent-soft);color:var(--accent)}
.st-running{background:var(--warn-soft);color:var(--warn)}
.st-waiting_user{background:var(--bad-soft);color:var(--bad)}
.st-waiting_sub{background:var(--warn-soft);color:var(--warn)}
.tree{margin:var(--sp-3) 0 0 var(--sp-3);padding-left:var(--sp-6);border-left:2px solid var(--line)}
.branch{padding:var(--sp-4) 0 var(--sp-2);border-top:1px dashed var(--line)}.branch:first-child{border-top:0}
.st-done,.st-active{background:var(--ok-soft);color:var(--ok)}
.st-failed,.st-rejected{background:var(--bad-soft);color:var(--bad)}
pre{white-space:pre-wrap;word-break:break-word;margin:var(--sp-3) 0;font:var(--text-note)/var(--lh-code) var(--font-mono);background:var(--bg);padding:var(--sp-4) var(--sp-5);border-radius:var(--radius-md);max-height:420px;overflow:auto}
.sheet{max-width:640px!important;max-height:88vh}
.sheet h2{font-size:var(--text-sheet-title)!important}
@keyframes fadein{from{opacity:0}}
/* 过渡：切页、弹层、菜单、新消息、提示都轻轻淡入；#view 本身只淡入不位移（对话页有 fixed 的输入区，加 transform 会错位） */
@keyframes rise{from{opacity:0;transform:translateY(8px)}}
@keyframes pop{from{opacity:0;transform:translateY(-4px) scale(.98)}}
@keyframes toast-in{from{opacity:0;transform:translate(-50%,8px)}}
#view.view-in{animation:fadein var(--dur-enter) ease-out}
#view.view-in > :not(.chatcol){animation:rise var(--dur-rise) var(--ease-emphasized)}
.msg.in{animation:rise var(--dur-msg) var(--ease-emphasized)}
.modal{animation:fadein var(--dur-scrim) ease-out}.modal-box{animation:rise var(--dur-pop) var(--ease-emphasized)}
.drop.open .menu,#topmenu.open .tpanel{animation:pop var(--dur-hover) ease-out}
.toast{animation:toast-in var(--dur-fade) ease-out}.toast.out{opacity:0;transform:translate(-50%,8px);transition:opacity var(--dur-enter),transform var(--dur-enter)}
#nav button,#bnav button,button.btn,.hubcard,.titem,.sugg button,.seg button,.filters button,.pill{transition:background-color var(--dur-hover),border-color var(--dur-hover),color var(--dur-hover),transform var(--dur-press)}
#nav button:active,#bnav button:active,button.btn:active,.hubcard:active,.titem:active,.sugg button:active,.pill:active{transform:scale(.98)}
@media (prefers-reduced-motion:reduce){*,::before,::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
.progress{height:6px;background:var(--line);border-radius:var(--radius-pill);overflow:hidden;margin:var(--sp-4) 0}
.progress>div{height:100%;background:var(--accent)}
.filters{display:flex;gap:var(--sp-3);flex-wrap:wrap;margin-bottom:var(--sp-6)}
.filters button{border:1px solid var(--line);background:var(--panel);color:var(--muted);border-radius:var(--radius-pill);padding:3px var(--sp-6);cursor:pointer;font:inherit;font-size:var(--text-caption)}
.filters button.on{border-color:var(--accent);color:var(--accent)}
details summary{cursor:pointer;color:var(--muted);font-size:var(--text-caption);margin-top:var(--sp-3)}
.ev{border-left:2px solid var(--line);padding:var(--sp-1) 0 var(--sp-3) var(--sp-5);margin-left:var(--sp-2)}
.ev b{font-weight:var(--fw-semibold)}
.form{display:grid;gap:var(--sp-4)}
.title{font-weight:var(--fw-semibold);cursor:pointer}
.empty{text-align:center;color:var(--muted);padding:var(--sp-20) 0}
.typing{color:var(--muted);font-size:var(--text-caption);padding:var(--sp-2) var(--sp-1)}
.modal{position:fixed;inset:0;background:var(--scrim);display:flex;align-items:center;justify-content:center;z-index:var(--z-modal);padding:var(--sp-8)}
.modal.hidden{display:none}
.linkbtn{background:none;border:0;padding:var(--sp-1) var(--sp-2);font:inherit;cursor:pointer;border-radius:var(--radius-sm)}
.drop{position:relative;display:inline-block}
.drop .menu{display:none;position:absolute;top:calc(100% + 4px);left:0;z-index:var(--z-menu);min-width:180px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-menu);padding:var(--sp-3);box-shadow:var(--shadow-menu)}
.drop.open .menu{display:block}
.drop .menu button{display:block;width:100%;text-align:left;border:0;background:none;padding:7px var(--sp-5);border-radius:var(--radius-sm);font:inherit;color:inherit;cursor:pointer;white-space:nowrap}
.drop .menu button:hover,.drop .menu button.on{background:var(--accent-soft);color:var(--accent)}
.drop .menu .item{padding:var(--sp-3) var(--sp-5);font-size:var(--text-small)}
nav .drop .menu{left:auto;right:0}
.chk{width:22px;height:22px;flex:none;border-radius:50%;border:2px solid var(--accent);background:none;color:var(--accent);cursor:pointer;font-size:var(--text-caption);line-height:1;padding:0}
.chk:hover{background:var(--accent);color:var(--bg)}.chk.off{border-color:var(--line);cursor:default}
.linkbtn:hover{background:var(--hover);color:var(--text)}
.modal-box{background:var(--panel);color:var(--text);border-radius:var(--r-card);padding:var(--sp-9) var(--sp-9) var(--sp-7);width:100%;max-width:440px;max-height:90vh;overflow:auto;box-shadow:var(--shadow-dialog)}
.modal-box h2{margin:0 0 var(--sp-2);font-size:var(--text-heading)}
.modal-box label{display:block;font-size:var(--text-caption);color:var(--muted);margin:var(--sp-5) 0 var(--sp-2)}
.modal-box .help{font-size:var(--text-caption);color:var(--muted);margin-top:var(--sp-2)}
.modal-box .err{color:var(--bad);font-size:var(--text-small);margin-top:var(--sp-5);white-space:pre-wrap}
.modal-box .safe{font-size:var(--text-caption);color:var(--ok);margin-top:var(--sp-4)}
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--text);color:var(--bg);padding:var(--sp-4) var(--sp-8);border-radius:var(--radius-pill);font-size:var(--text-small);z-index:var(--z-toast)}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
