:root{color-scheme:light;--bg:#f5f4f1;--surface:#fff;--subtle:#f0efec;--text:#21242c;--muted:#626875;--line:#dedfe3;--accent:#ad3157;--soft:#f9e8ee}
:root.dark{color-scheme:dark;--bg:#10131b;--surface:#1b202c;--subtle:#232a38;--text:#f2f3f7;--muted:#b0b7c5;--line:#333c4d;--accent:#ffa1bc;--soft:#352536}
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:15px/1.6 var(--portal-font-sans)}a{color:inherit;text-decoration:none}button,input{font:inherit}button,summary{cursor:pointer}button{color:var(--text);background:var(--surface);border:1px solid var(--line);border-radius:9px;padding:8px 12px}button:hover{border-color:var(--accent)}button[aria-pressed=true]{background:var(--soft);color:var(--accent);border-color:var(--accent)}:focus-visible{outline:3px solid var(--accent);outline-offset:3px}[hidden]{display:none!important}
.home{max-width:1080px;margin:auto;padding:32px 24px}.masthead{display:flex;align-items:start;justify-content:space-between;gap:16px;margin-bottom:24px}.masthead h1{font-size:34px;line-height:1.2;letter-spacing:-1px;margin:0 0 8px}.masthead p{margin:0;color:var(--muted)}.eyebrow{font:11px/1.5 ui-monospace,monospace;letter-spacing:.14em;color:var(--accent);margin:0 0 8px}.toolbar{display:flex;gap:8px;flex-shrink:0}.quick-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.quick-head h2{font-size:17px;margin:0}.quick-head{margin-bottom:10px}.hint{font-size:12px;color:var(--muted)}.quick-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}.quick-link{display:flex;align-items:center;gap:10px;border:1px solid var(--line);background:var(--surface);border-radius:12px;padding:14px;min-height:60px;font-weight:600;transition:border-color .18s,transform .18s}.quick-link:hover{border-color:var(--accent);background:var(--soft);transform:translateY(-1px)}.quick-link .icon{display:grid;place-items:center;flex:0 0 30px;width:30px;height:30px;border-radius:9px;background:var(--subtle);font-size:18px}.manage p{color:var(--muted);font-size:13px}.manage-columns{display:flex;flex-direction:column;gap:10px;margin-top:4px}
.manage-col{display:flex;flex-direction:column;gap:8px;border:1px solid var(--line);border-radius:12px;background:var(--subtle);padding:10px 12px}
.manage-col-title{display:flex;align-items:center;gap:8px;font-size:12px;letter-spacing:.06em;color:var(--muted);margin:0}
.manage-col .manage-col-hint{margin:0;font-size:11.5px}
/* 单列纵向：序号自上而下 1、2、3…，与「第几位」的直觉一致。
   原来用 repeat(auto-fit,minmax(380px,1fr))，列数随视口宽度变化——窄屏 1 列、
   宽屏 2 列、更宽还可能 3 列，同一份数据在不同窗口下读出来的顺序都不一样，
   而这一列的顺序正是用户拿来判断首页排列的唯一依据。 */
.manage-list{list-style:none;display:grid;grid-template-columns:1fr;gap:6px;margin:0;padding:0;min-height:40px}
.manage-list:empty::after{content:'（暂无）';font-size:12px;color:var(--muted);padding:10px 2px}
.manage-item{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:9px;background:var(--surface);padding:6px 9px;font-size:13px}
.manage-item:hover{border-color:var(--accent)}
.manage-item.dragging{opacity:.55;border-style:dashed;background:var(--ui-raised)}
/* 拖动手柄：touch-action:none 是关键——缺了它手机上按下会先被当成滚动页面，拖不动。 */
.manage-item .grip{color:var(--muted);font-size:14px;line-height:1;user-select:none;cursor:grab;touch-action:none;padding:3px 2px}
.manage-item .grip:active{cursor:grabbing}
/* 位次徽标：这个入口在首页的第几位。等宽数字，拖动时连续变化，
   不必另开预览区就能看出落点。 */
.manage-item .manage-pos{
  flex:none;min-width:21px;height:20px;padding:0 5px;border-radius:6px;
  background:var(--ui-raised);color:var(--ui-muted);
  font-size:11px;font-weight:600;font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:center;justify-content:center;
}
.manage-item.dragging .manage-pos{background:var(--ui-accent);color:var(--ui-on-accent)}
.manage-item .manage-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.manage-toggle{font-size:11.5px;padding:3px 9px;border-radius:7px}.reset{margin-top:12px}footer{margin-top:36px;border-top:1px solid var(--line);padding-top:20px;color:var(--muted);font-size:13px}footer summary{color:var(--text)}footer a{text-decoration:underline;text-underline-offset:3px}.storage-note{font-size:12px;color:var(--accent)}
@media(max-width:700px){.home{padding:22px 16px}.masthead h1{font-size:29px}.masthead p{font-size:13px}.toolbar button{font-size:12px;padding:6px 8px}.quick-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.quick-link{min-height:52px;padding:10px;font-size:13px;gap:7px}.quick-link .icon{width:26px;height:26px;flex-basis:26px;font-size:17px}.manage-list{grid-template-columns:1fr}.masthead{gap:8px;margin-bottom:20px}.quick-head .hint{font-size:11px}}
@media(prefers-reduced-motion:reduce){*{transition:none!important;scroll-behavior:auto!important}}

.x-widget{margin-top:24px;padding:22px;border:1px solid var(--line);border-radius:16px;background:var(--surface)}
.x-heading{display:flex;justify-content:space-between;align-items:center;gap:16px}.x-heading :is(h1,h2){font-size:20px;line-height:1.4;margin:3px 0 6px}.x-heading .eyebrow{margin:0}.x-subtitle{margin:0;color:var(--muted);font-size:12px}.x-subtitle a,.x-list a{color:var(--accent)}.x-heading button{flex-shrink:0;font-size:12px}.x-heading button:disabled{opacity:.5;cursor:wait}.x-count{display:inline-block;vertical-align:middle;font-size:11px;font-weight:500;margin-left:8px;padding:3px 9px;border-radius:20px;background:var(--soft);color:var(--accent)}
.x-status{font-size:12px;color:var(--muted);margin:14px 0 10px}.x-widget[data-state=stale] .x-status,.x-widget[data-state=unavailable] .x-status{color:var(--accent)}.x-list{list-style:none;padding:0;margin:0;max-height:440px;overflow:auto;scrollbar-width:thin}.x-list li{padding:16px 0;border-top:1px solid var(--line)}.x-post-head{display:flex;gap:12px;flex-wrap:wrap;justify-content:space-between;font-size:12px;color:var(--muted)}.x-post-head span{font-weight:600;color:var(--text)}.x-post-text{font-size:14px;line-height:1.7;white-space:pre-wrap;overflow-wrap:anywhere;margin:8px 0}.x-list a{font-size:12px}.x-list a:hover,.x-subtitle a:hover{text-decoration:underline}.x-coverage{font-size:11px;color:var(--muted);margin:12px 0 0;padding-top:12px;border-top:1px solid var(--line)}.x-empty{color:var(--muted);font-size:13px;padding:12px 0}
@media(max-width:700px){.x-widget{padding:16px}.x-heading{align-items:flex-start;gap:10px}.x-heading :is(h1,h2){font-size:17px}.x-heading button{padding:7px 9px}.x-count{margin-left:2px}.x-subtitle{font-size:11px}.x-list{max-height:400px}}

.x-language-label{font-size:11px;color:var(--muted);margin-top:10px}.x-translation{border-left:2px solid var(--line);padding-left:12px;margin:10px 0 12px}.x-translation .x-language-label{margin-top:0}
.x-quote{margin:12px 0;padding:12px;border:1px solid var(--line);border-radius:10px;background:var(--soft)}.x-quote-heading{font-weight:600}

.x-page .x-list{max-height:none;overflow:visible}.x-page .masthead a{font-size:13px;color:var(--accent)}

/* /x-updates/ 的主功能：服务器中转访问 X（采集快照区块保留在下方，作为直连不可用时的只读兜底） */
.x-relay{margin-top:24px;padding:22px;border:1px solid var(--line);border-radius:16px;background:var(--surface);display:flex;flex-direction:column;gap:14px}
.x-relay-copy :is(h1,h2){font-size:20px;line-height:1.4;margin:3px 0 8px}
.x-relay-copy .eyebrow{margin:0}
.x-relay-copy .x-subtitle{margin:0;max-width:70ch}
.x-relay-copy code{font-family:ui-monospace,monospace;font-size:12px;color:var(--accent)}
.x-relay-open{align-self:flex-start;display:inline-flex;align-items:center;gap:8px;padding:10px 16px;border:1px solid var(--accent);border-radius:10px;color:var(--accent);font-weight:600;font-size:14px}
.x-relay-open:hover{background:var(--soft)}
.x-relay-note{margin:0;font-size:11.5px;color:var(--muted);max-width:80ch}
@media(max-width:700px){.x-relay{padding:16px}.x-relay-copy :is(h1,h2){font-size:17px}.x-relay-copy .x-subtitle{font-size:12px}.x-relay-open{font-size:13px;padding:9px 13px}}

/* 首页组件卡片设计规范：<details class="panel …"> 承载组件，<summary> 里放标题与一句话 brief，
   正文放 details 内；展开状态由脚本写入 wujiang-portal-* 键。新增组件沿用 .panel，
   不要各自再写一套折叠样式与逻辑。 */
.panel{margin:12px 0;border:1px solid var(--line);border-radius:12px;background:var(--surface);padding:12px 16px}
.panel>summary{display:flex;align-items:baseline;gap:8px;min-height:28px;font-weight:600;list-style:none}
.panel>summary::-webkit-details-marker{display:none}
.panel>summary::before{content:'▸';flex:none;color:var(--muted);transition:transform .18s}
.panel[open]>summary::before{transform:rotate(90deg)}
.panel-title{font-size:15px}
.panel-brief{font-weight:400;font-size:12px;color:var(--muted)}
.panel[open]>summary{margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--line)}

/* 数据抓取日志：语义色跟随明暗主题，状态点只在徽标与左侧竖线上出现 */
:root{--log-ok:#1f7a4d;--log-warn:#8a5200;--log-fail:#b3261e}
:root.dark{--log-ok:#7ee2a8;--log-warn:#f2c268;--log-fail:#ff9d94}
.log-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}
.log-head .eyebrow{margin:0 0 6px}.log-head .hint{margin:0}
.log-tools{display:flex;gap:6px;flex-wrap:wrap;flex-shrink:0}.log-tools button{font-size:12px;padding:6px 10px}
.log-status{font-size:12px;color:var(--muted);margin:6px 0 0}
.log-body{margin-top:12px;display:flex;flex-direction:column;gap:8px}
.log-projects,.log-tasks,.log-timeline{list-style:none;margin:0;padding:0}
.log-project{border:1px solid var(--line);border-radius:10px;background:var(--subtle);padding:10px 12px}
.log-project-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.log-project-name{font-weight:600;font-size:13.5px}.log-project-name:hover{color:var(--accent)}
.log-project-note{font-size:12px;color:var(--muted);margin:6px 0 0}
.log-tasks{margin-top:8px;padding-top:8px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:8px}
.log-task{border-left:2px solid var(--line);padding-left:10px}
.log-task[data-state=ok]{border-left-color:var(--log-ok)}.log-task[data-state=warn]{border-left-color:var(--log-warn)}.log-task[data-state=fail]{border-left-color:var(--log-fail)}
.log-task-head,.log-event-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12.5px}
.log-task-name{font-weight:600}
.log-task-schedule{color:var(--muted);font-size:11.5px}
.log-time{font:11.5px/1.5 ui-monospace,monospace;color:var(--muted)}
.log-badge{font-size:11px;padding:1px 8px;border-radius:20px;border:1px solid currentColor;color:var(--muted);white-space:nowrap}
.log-badge[data-state=ok]{color:var(--log-ok)}.log-badge[data-state=warn]{color:var(--log-warn)}.log-badge[data-state=fail]{color:var(--log-fail)}
.log-note{font-size:12px;color:var(--muted);margin:4px 0 0;overflow-wrap:anywhere}
.log-timeline{display:flex;flex-direction:column}
.log-event{border-top:1px solid var(--line);padding:9px 0}
.log-event:first-child{border-top:0;padding-top:0}
.log-event-project{font-weight:600;font-size:12.5px}.log-event-project:hover{color:var(--accent)}
.log-event-task{color:var(--muted);font-size:12px}
@media(max-width:700px){.panel{padding:12px}.panel>summary{flex-wrap:wrap;column-gap:7px}.panel-brief{flex:0 0 100%;padding-left:17px}.log-tools button{font-size:11.5px;padding:5px 8px}.log-task-schedule{display:none}}


/* 首页入口说明：名称与用途同时可见，目录数量变化时仍无需搜索。 */
.quick-link{min-height:72px;padding:12px;align-items:flex-start}
.quick-copy{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.quick-name{font-weight:600;line-height:1.35}
.quick-link small{display:block;color:var(--muted);font-size:11px;font-weight:400;line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.quick-link:hover .quick-name{color:var(--accent)}

/* 管理入口：桌面可拖拽，触屏与键盘可用方向按钮完成同样操作。 */
.manage-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:10px}
.manage-head p{margin:0;max-width:70ch}
.manage-head button{flex-shrink:0}
.manage-columns{align-items:stretch}
.manage-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}
.manage-move,.manage-toggle{font-size:11.5px;line-height:1.2;padding:4px 7px;border-radius:7px;cursor:pointer;touch-action:manipulation}
.manage-move{width:27px;padding:4px 0}
.manage-move:disabled{opacity:.3;cursor:default}
.manage-status{min-height:20px;margin:8px 0 0;color:var(--muted);font-size:12px}

/* 自动任务状态与反馈回退。 */
.log-tools button:disabled{opacity:.6;cursor:wait}
.log-event[data-state=warn]{border-left:2px solid var(--log-warn);padding-left:9px}
.log-event[data-state=fail]{border-left:2px solid var(--log-fail);padding-left:9px}
.feedback-fallback{width:100%;min-height:150px;margin-top:8px;padding:10px;border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--text);font:12px/1.5 ui-monospace,monospace;resize:vertical}
@media(max-width:700px){
  .quick-link{min-height:64px;padding:9px;gap:7px}
  .quick-link small{font-size:10.5px}
  .manage-head{flex-direction:column;gap:8px}
  .manage-head button{width:100%}
  .manage-item{gap:6px;padding:6px}
  .manage-move{width:30px;min-height:30px}
  .manage-toggle{min-height:30px;padding-inline:8px}
}
