feat(web): 用户端骨架——登录、工作台、新建项目、解析进度、读标清单
- packages/api-client:从 openapi.yaml 生成类型;cookie + CSRF / Bearer 两种鉴权、 分片上传、fetch 读事件流(API2) - apps/web:Vue 3 + Vite + TanStack Query,样式只来自 tokens.css / components.css(AR10); 扣点说明放在「开始解析」旁边(红线 9);接口地址、路由方式运行时可配(架构 §5.2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
242
apps/web/src/styles/app.css
Normal file
242
apps/web/src/styles/app.css
Normal file
@@ -0,0 +1,242 @@
|
||||
/* 标博士用户端 · 页面框架与共用小件
|
||||
* 视觉来源:docs/design/system/tokens.css + components.css(main.ts 通过 @design 别名直接引用,不复制)。
|
||||
* 本文件只放这两份文件里还没有的「页面框架层」:侧栏、顶栏、页头、项目头,以及原型 docs/prototype/assets/app.css
|
||||
* 第 1、2 部分里本应用用到的那几块(B1 图标、B3 按钮状态、B4 输入、B7 复选、B8 标签页、B11 对话框、B13 提示气泡、
|
||||
* B14 空状态与进度、B15 杂项、B16 AI 块、B17 统计、B19 分类导航、B20 项目行),选择器和写法照搬原型。
|
||||
* 只用 tokens.css 的变量,不写裸色值。
|
||||
* TODO:这一层应提升到 docs/design/system(或 packages/ui)作为唯一来源,届时删掉本文件里的副本。
|
||||
* 与原型的差别:原型把框架挂在 body.app 上,这里挂在 AppShell 的根元素 .app-frame 上。 */
|
||||
|
||||
/* =====================================================================
|
||||
* 1. 页面框架:96px 墨色渐变侧栏 + 透明顶栏 + 内容区左上角圆角
|
||||
* ===================================================================== */
|
||||
.app-frame{display:grid;grid-template-columns:var(--rail-w) minmax(0,1fr);min-height:100vh;min-width:1280px;background:linear-gradient(180deg,var(--side-top) 0%,var(--side-bottom) 100%) fixed}
|
||||
.sidebar{position:sticky;top:0;height:100vh;display:flex;flex-direction:column;padding:0 0 var(--sp-4) 10px;color:var(--side-fg);min-width:0}
|
||||
.sidebar::after{content:"";position:absolute;left:0;right:0;bottom:0;height:260px;pointer-events:none;background-image:radial-gradient(var(--side-dots) 1px,transparent 1.2px);background-size:14px 14px;-webkit-mask-image:linear-gradient(to top,black,transparent);mask-image:linear-gradient(to top,black,transparent)}
|
||||
.sidebar > *{position:relative;z-index:1}
|
||||
.sidebar .brand{display:flex;justify-content:center;padding:var(--sp-5) 10px var(--sp-5) 0;border-radius:var(--radius-ctl)}
|
||||
.sidebar .brand img{width:60px;height:auto;display:block}
|
||||
.sidebar .nav{display:flex;flex-direction:column;gap:var(--sp-1)}
|
||||
.sidebar .nav a{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-1);height:62px;margin-right:10px;border-radius:var(--radius-card);font-size:var(--fs-caption);line-height:16px;color:var(--side-fg);text-align:center;text-decoration:none;white-space:nowrap;transition:background-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
|
||||
.sidebar .nav a .ic{width:22px;height:22px}
|
||||
.sidebar .nav a:hover{background:var(--side-hover);color:var(--side-fg-strong)}
|
||||
.sidebar .nav a[aria-current]{background:var(--side-active);color:var(--side-fg-strong);font-weight:var(--fw-bold)}
|
||||
.sidebar a:focus-visible,.sidebar button:focus-visible{outline:2px solid var(--side-fg-strong);outline-offset:-2px}
|
||||
.sidebar .me{display:flex;flex-direction:column;align-items:center;margin-top:auto;padding:var(--sp-4) 10px var(--sp-1) 0;color:var(--side-muted);text-align:center}
|
||||
.sidebar .avatar{display:inline-grid;place-items:center;width:44px;height:44px;margin-bottom:var(--sp-2);border-radius:50%;background:var(--side-avatar-bg);box-shadow:0 0 0 1px var(--side-avatar-ring);color:var(--side-fg-strong);font-size:var(--fs-title);font-weight:var(--fw-bold)}
|
||||
.sidebar .uname{color:var(--side-fg-strong);font-size:var(--fs-body);line-height:var(--lh-body);font-weight:var(--fw-bold);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
/* 套餐标签:只在账户区使用;免费版中性、专业版浅金、企业版金色实底 */
|
||||
.plan{display:inline-block;margin-top:var(--sp-1);padding:0 var(--sp-2);border-radius:var(--radius-xs);font-size:var(--fs-caption);line-height:20px;font-weight:var(--fw-bold);white-space:nowrap}
|
||||
.plan[data-plan="free"]{background:var(--plan-free-bg);color:var(--side-fg)}
|
||||
.plan[data-plan="pro"]{background:var(--plan-pro-bg);color:var(--plan-pro-fg);box-shadow:inset 0 0 0 1px var(--plan-pro-line)}
|
||||
.plan[data-plan="ent"]{background:var(--plan-ent-bg);color:var(--c-ink)}
|
||||
|
||||
.main{min-width:0;display:flex;flex-direction:column;min-height:100vh;background:var(--bg-page);border-top-left-radius:var(--radius-card)}
|
||||
.top{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:var(--sp-3);height:var(--topbar-h);padding:0 var(--pad-page);background:transparent;border-bottom:var(--line) solid transparent;border-top-left-radius:var(--radius-card);transition:background-color var(--dur-base) var(--ease),border-color var(--dur-base) var(--ease)}
|
||||
.top.scrolled{background:var(--topbar-glass);-webkit-backdrop-filter:blur(14px) saturate(1.2);backdrop-filter:blur(14px) saturate(1.2);border-bottom-color:var(--border-subtle)}
|
||||
.crumbs{display:flex;align-items:center;gap:6px;min-width:0;color:var(--text-secondary);white-space:nowrap;overflow:hidden}
|
||||
.crumbs > *{min-width:0;overflow:hidden;text-overflow:ellipsis}
|
||||
.crumbs > span{flex:none}
|
||||
.crumbs .org{flex:none;color:var(--text-primary);font-weight:var(--fw-bold)}
|
||||
.crumbs a{color:var(--text-secondary);text-decoration:none}
|
||||
.crumbs a:hover{color:var(--text-primary);text-decoration:underline;text-decoration-color:var(--link-underline);text-underline-offset:3px}
|
||||
.crumbs b{font-weight:var(--fw-regular)}
|
||||
.top-right{display:flex;align-items:center;gap:var(--sp-1);flex:none;margin-left:auto}
|
||||
/* 顶栏额度:用到 ≥ 80% 时该项数字变赭色加粗(.warn);不用红 */
|
||||
.quota-chip{display:inline-flex;align-items:center;gap:6px;height:var(--control-h-sm);padding:0 10px;border-radius:var(--radius-ctl);color:var(--text-secondary);text-decoration:none;white-space:nowrap}
|
||||
.quota-chip .q{display:inline-flex;align-items:baseline;gap:6px}
|
||||
.quota-chip .fig{color:var(--text-primary);font-size:var(--fs-figure-sm)}
|
||||
.quota-chip .q.warn .fig{color:var(--warn-text);font-weight:var(--fw-bold)}
|
||||
.quota-chip .sep{width:1px;height:12px;margin:0 var(--sp-1);background:var(--border-subtle)}
|
||||
.top .vsep{flex:none;width:1px;height:20px;margin:0 var(--sp-1);background:var(--border-subtle)}
|
||||
.content{width:100%;padding:20px var(--pad-page) var(--sp-12)}
|
||||
.content.narrow{max-width:800px}
|
||||
/* 页头:标题 + 一句话;右侧放页面级主按钮(Q12:页面级一个) */
|
||||
.page-title{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-6);margin-bottom:20px}
|
||||
.page-title h1{font:var(--fw-bold) var(--fs-h1)/var(--lh-h1) var(--font-serif);margin:0}
|
||||
.page-title p{margin:2px 0 0;color:var(--text-secondary)}
|
||||
.page-title .actions{margin-left:auto;display:flex;gap:var(--sp-3);align-items:center}
|
||||
.stack > * + *{margin-top:var(--gap-card)}
|
||||
|
||||
/* 项目头(项目内页面):名称 + 信息一行;右侧截止、状态;下方标签页 */
|
||||
.ph{padding:var(--sp-1) var(--pad-page) 0}
|
||||
.ph-l1{display:flex;align-items:flex-end;gap:var(--sp-8)}
|
||||
.ph-l1 > div{min-width:0}
|
||||
.ph h1{margin:0;font:var(--fw-bold) var(--fs-h1)/var(--lh-h1) var(--font-serif);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.ph-meta{margin:2px 0 0;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.ph .facts{display:flex;gap:var(--sp-8);margin:0 0 0 auto;flex:none}
|
||||
.ph .facts > div{display:flex;flex-direction:column;gap:2px}
|
||||
.ph .facts dt{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary)}
|
||||
.ph .facts dd{display:flex;align-items:center;gap:6px;min-height:var(--lh-body);margin:0;white-space:nowrap}
|
||||
.ph .tabs{margin-top:var(--sp-3)}
|
||||
.ph + .content{padding-top:var(--sp-5)}
|
||||
|
||||
/* =====================================================================
|
||||
* 2. 共用小件
|
||||
* ===================================================================== */
|
||||
/* B1 图标(Lucide 线性,1.5px 描边,16 / 20px;侧栏菜单 22px) */
|
||||
.ic{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;vertical-align:-3px}
|
||||
.ic.lg{width:20px;height:20px}
|
||||
.ic.xl{width:32px;height:32px;stroke-width:1.25}
|
||||
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
||||
|
||||
/* B3 按钮补充状态:加载中两个文字叠在同一格,切换时宽度不变 */
|
||||
.btn .ic{margin:0 -2px}
|
||||
.btn.swap{display:inline-grid;place-items:center}
|
||||
.btn.swap > span{grid-area:1/1;white-space:nowrap}
|
||||
.btn.swap > .busy,.btn.swap.is-loading > .idle{visibility:hidden}
|
||||
.btn.swap.is-loading > .busy{visibility:visible}
|
||||
.btn.is-loading{cursor:progress}
|
||||
.btn.primary.is-loading{background:var(--primary-hover);border-color:var(--primary-hover)}
|
||||
.icon-btn{position:relative;flex:none;display:inline-grid;place-items:center;width:var(--control-h);height:var(--control-h);padding:0;border:var(--line) solid transparent;border-radius:var(--radius-ctl);background:none;color:var(--text-primary);cursor:pointer;transition:background-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
|
||||
.icon-btn:hover{background:var(--c-n100)}
|
||||
.icon-btn.sm{width:var(--control-h-sm);height:var(--control-h-sm)}
|
||||
|
||||
/* B4 输入框 */
|
||||
.input{width:100%;transition:border-color var(--dur-fast) var(--ease)}
|
||||
.input:hover{border-color:var(--c-ink)}
|
||||
.input:focus{outline:0;border-color:var(--c-ink);box-shadow:0 0 0 1px var(--c-ink)}
|
||||
.field.err .input:focus{border-color:var(--warn);box-shadow:0 0 0 1px var(--warn)}
|
||||
.input[disabled]{background:var(--c-n100);border-color:var(--c-n100);color:var(--text-disabled);cursor:not-allowed}
|
||||
.field label{display:flex;gap:var(--sp-1);align-items:baseline}
|
||||
.field label small{margin-left:2px}
|
||||
.field .choice{display:inline-flex;gap:var(--sp-2);align-items:flex-start;font-weight:var(--fw-regular)}
|
||||
.hint-warn{display:flex;gap:6px;align-items:flex-start;margin:0;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--warn-text)}
|
||||
.hint-warn .ico{flex:none;width:14px;height:14px;font-size:10px;margin:3px 0 0}
|
||||
.field + .field{margin-top:0}
|
||||
.search{position:relative;display:block}
|
||||
.search > .ic{position:absolute;left:11px;top:10px;color:var(--text-secondary);pointer-events:none}
|
||||
.search .input{padding-left:34px}
|
||||
|
||||
/* B7 复选框 */
|
||||
.ck{appearance:none;flex:none;display:inline-grid;place-content:center;width:16px;height:16px;margin:0;border:var(--line) solid var(--border-control);border-radius:var(--radius-xs);background:var(--bg-surface);cursor:pointer;vertical-align:-3px}
|
||||
.ck:hover{border-color:var(--c-ink)}
|
||||
.ck::after{content:"";display:none}
|
||||
.ck:checked{background:var(--c-ink);border-color:var(--c-ink)}
|
||||
.ck:checked::after{display:block;width:8px;height:4px;border:solid var(--c-white);border-width:0 0 1.75px 1.75px;transform:translateY(-1px) rotate(-45deg)}
|
||||
.choice{display:inline-flex;gap:var(--sp-2);align-items:flex-start;cursor:pointer;line-height:var(--lh-body)}
|
||||
.choice .ck{margin-top:3px}
|
||||
|
||||
/* B8 标签页 */
|
||||
.tabs{display:flex;gap:var(--sp-6);border-bottom:var(--line) solid var(--border-subtle)}
|
||||
.tabs [role=tab]{display:flex;gap:6px;align-items:center;margin-bottom:-1px;padding:var(--sp-2) 0 10px;border:0;border-bottom:2px solid transparent;background:none;font:var(--fs-body) var(--font-sans);color:var(--text-secondary);cursor:pointer;text-decoration:none;white-space:nowrap}
|
||||
.tabs [role=tab]:hover{color:var(--text-primary)}
|
||||
.tabs [role=tab][aria-selected="true"]{color:var(--text-primary);font-weight:var(--fw-bold);border-bottom-color:var(--c-ink)}
|
||||
|
||||
/* B11 对话框(480 / 640,圆角 12;对话框里可以有自己的主按钮) */
|
||||
.scrim{position:fixed;inset:0;z-index:50;display:grid;overflow:auto;padding:var(--sp-8) var(--sp-4);background:var(--scrim)}
|
||||
.dialog{position:relative;margin:auto;width:480px;max-width:100%;padding:var(--sp-6);background:var(--bg-surface);border-radius:var(--radius-card);box-shadow:var(--shadow-overlay)}
|
||||
.dialog h2{font:var(--fw-bold) var(--fs-title)/var(--lh-title) var(--font-sans);margin:0 var(--sp-8) var(--sp-3) 0}
|
||||
.dialog .body > p{margin:0 0 var(--sp-3)}
|
||||
.dialog .foot{display:flex;justify-content:flex-end;align-items:center;gap:var(--sp-2);margin-top:var(--sp-6)}
|
||||
|
||||
/* B12 提醒补充 */
|
||||
.alert > div{flex:1;min-width:0}
|
||||
.alert > p{flex:1}
|
||||
.alert .sub{display:block;margin-top:2px;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary)}
|
||||
.errno{font:var(--fw-medium) var(--fs-figure-xs)/1 var(--font-figures);color:var(--text-secondary);letter-spacing:.02em}
|
||||
|
||||
/* B13 提示气泡(悬停 / 聚焦显示) */
|
||||
[data-tip]{position:relative}
|
||||
[data-tip]:hover::after,[data-tip]:focus-visible::after{content:attr(data-tip);position:absolute;z-index:55;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);width:max-content;max-width:280px;padding:6px 10px;border-radius:var(--radius-ctl);background:var(--c-ink);color:var(--text-on-dark);font:var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font-sans);white-space:normal;text-align:left;pointer-events:none}
|
||||
[data-tip].tip-below:hover::after,[data-tip].tip-below:focus-visible::after{bottom:auto;top:calc(100% + 8px)}
|
||||
[data-tip].tip-left:hover::after,[data-tip].tip-left:focus-visible::after{left:auto;right:0;transform:none}
|
||||
|
||||
/* B14 空状态、骨架屏、进度(骨架屏静止,Q8) */
|
||||
.empty{display:flex;flex-direction:column;align-items:center;text-align:center;padding:var(--sp-12) var(--sp-6)}
|
||||
.empty > .ic{color:var(--text-secondary);margin-bottom:var(--sp-3)}
|
||||
.empty b{font-size:var(--fs-title);line-height:var(--lh-title)}
|
||||
.empty p{margin:var(--sp-1) 0 var(--sp-5);color:var(--text-secondary);max-width:30em}
|
||||
.empty.sm{padding:var(--sp-8) var(--sp-4)}
|
||||
.empty.sm b{font-size:var(--fs-body);line-height:var(--lh-body)}
|
||||
.empty.sm p{margin-bottom:0}
|
||||
.empty.sm > .btn{margin-top:var(--sp-4)}
|
||||
.skel{display:block;height:12px;border-radius:var(--radius-xs);background:var(--c-n100)}
|
||||
.skel.t{height:16px;width:40%}
|
||||
.skel + .skel{margin-top:var(--sp-2)}
|
||||
.progress{display:flex;align-items:center;gap:10px}
|
||||
.progress .bar{flex:1;margin:0}
|
||||
.progress .fig{min-width:3em;text-align:right}
|
||||
.steps .dot{line-height:1;font-family:var(--font-sans)}
|
||||
.steps li > span:nth-child(2){flex:1}
|
||||
.steps .fail .dot{border-color:var(--warn);color:var(--warn-text);font-weight:var(--fw-bold)}
|
||||
.steps .fail{color:var(--warn-text)}
|
||||
|
||||
/* B15 杂项小件 */
|
||||
.kbd{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 6px;border-radius:var(--radius-tag);background:var(--c-n100);font:var(--fw-bold) var(--fs-caption)/1 var(--font-figures);color:var(--text-secondary);white-space:nowrap}
|
||||
.muted{color:var(--text-secondary)}
|
||||
.cap{font-size:var(--fs-caption);line-height:var(--lh-caption)}
|
||||
.fig.m{font-weight:var(--fw-medium)}
|
||||
.fig.xs{font-size:var(--fs-figure-xs)}
|
||||
:is(.hint-warn,.stat p,.quota p) .fig{font-size:var(--fs-figure-xs)}
|
||||
.kv{display:grid;grid-template-columns:96px minmax(0,1fr);gap:var(--sp-2) var(--sp-4);margin:0}
|
||||
.kv dt{color:var(--text-secondary)}
|
||||
.kv dd{margin:0}
|
||||
.drop{display:flex;flex-direction:column;align-items:center;gap:var(--sp-1);border:1.5px dashed var(--border-control);border-radius:var(--radius-card);background:var(--bg-surface);padding:var(--sp-8) var(--sp-6);text-align:center;cursor:pointer;transition:background-color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)}
|
||||
.drop:hover,.drop.is-over{border-color:var(--c-ink);background:var(--c-n50)}
|
||||
.drop > .ic{color:var(--text-secondary)}
|
||||
.drop b{font-size:var(--fs-title);line-height:var(--lh-title)}
|
||||
.drop span{color:var(--text-secondary);font-size:var(--fs-caption);line-height:var(--lh-caption)}
|
||||
.drop[aria-disabled="true"]{pointer-events:none;color:var(--text-disabled);border-color:var(--border-subtle);background:var(--c-n50)}
|
||||
.file-row{display:grid;grid-template-columns:40px minmax(0,1fr);grid-auto-flow:column;grid-auto-columns:auto;gap:var(--sp-3);align-items:center;padding:var(--sp-3) var(--sp-4);background:var(--bg-surface);border:var(--line) solid var(--border-subtle);border-radius:var(--radius-card)}
|
||||
.file-row .ext{font:var(--fw-bold) 11px/1 var(--font-figures);background:var(--c-n100);border-radius:var(--radius-xs);padding:5px 0;text-align:center}
|
||||
.file-row b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
.file-row .acts{display:flex;gap:var(--sp-1);align-items:center}
|
||||
|
||||
/* B16 AI 产出块:确认前「AI」小标签 + 左侧 2px 蓝铅笔虚线;正文始终墨色(Q2) */
|
||||
.ai-block{border-left:2px dashed var(--ai);padding:var(--sp-1) 0 var(--sp-1) var(--sp-3);color:var(--text-primary)}
|
||||
|
||||
/* B17 卡片头、统计 */
|
||||
.card-h{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)}
|
||||
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));background:var(--bg-surface);border:var(--line) solid var(--border-subtle);border-radius:var(--radius-card);overflow:hidden}
|
||||
.stat{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:2px;min-width:0;padding:var(--sp-4) var(--card-x);border:0;border-left:var(--line) solid var(--border-subtle);background:none;font:inherit;color:inherit;text-align:left}
|
||||
.stat:first-child{border-left:0}
|
||||
.stat small{display:block;font-size:var(--fs-body);line-height:var(--lh-body);color:var(--text-secondary)}
|
||||
.stat .big{font:var(--fw-bold) var(--fs-figure)/var(--lh-figure) var(--font-figures);font-variant-numeric:tabular-nums}
|
||||
.stat .big.fatal{color:var(--sev-fatal)}
|
||||
.stat .big.due{color:var(--warn-text)}
|
||||
|
||||
/* B19 列表卡片:左侧分类导航 + 列表;列表里的分组标题(.ai 是清单顶部的「待确认」分组) */
|
||||
.cmp-list{display:grid;grid-template-columns:176px minmax(0,1fr);min-height:0;overflow:hidden}
|
||||
@media (max-width:1399px){.cmp-list{grid-template-columns:152px minmax(0,1fr)}}
|
||||
.cmp-list > .lst{position:relative;min-width:0}
|
||||
.cats{display:flex;flex-direction:column;gap:2px;border-right:var(--line) solid var(--border-subtle);padding:var(--sp-3) var(--sp-2)}
|
||||
.cats button{display:flex;flex:none;width:100%;align-items:center;justify-content:space-between;height:var(--control-h-sm);padding:0 10px;border:0;background:none;border-radius:var(--radius-ctl);font:var(--fs-body) var(--font-sans);color:var(--text-primary);cursor:pointer;text-align:left;transition:background-color var(--dur-fast) var(--ease)}
|
||||
.cats button:hover{background:var(--c-n100)}
|
||||
.cats button[aria-current="true"]{background:var(--c-n100);font-weight:var(--fw-bold)}
|
||||
.cats button .fig{font-size:var(--fs-figure-sm);font-weight:var(--fw-medium);color:var(--text-secondary)}
|
||||
.cats button.ai,.cats button.ai .fig{color:var(--ai)}
|
||||
.cats hr{width:100%;margin:var(--sp-2) 0;border:0;border-top:var(--line) solid var(--border-subtle)}
|
||||
.grp-h{display:flex;align-items:baseline;gap:var(--sp-2);padding:var(--sp-5) var(--card-x) var(--sp-2)}
|
||||
.grp-h b{font-weight:var(--fw-bold)}
|
||||
.grp-h .fig{font-weight:var(--fw-medium);color:var(--text-secondary)}
|
||||
.grp-h.ai b,.grp-h.ai .fig{color:var(--ai)}
|
||||
.grp-h p{margin:0;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary)}
|
||||
|
||||
/* B20 项目行:栅格对齐的列表,整行可点 */
|
||||
:root{--prow-cols:minmax(0,1fr) 120px 120px 64px 140px var(--control-h-sm);--prow-gap:var(--sp-4)}
|
||||
@media (max-width:1399px){:root{--prow-cols:minmax(0,1fr) 108px 108px 56px 132px var(--control-h-sm);--prow-gap:var(--sp-3)}}
|
||||
.prow-head,.prow{display:grid;grid-template-columns:var(--prow-cols);column-gap:var(--prow-gap);align-items:center;padding:0 var(--card-x)}
|
||||
.prow-head{padding-bottom:var(--sp-2);font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary)}
|
||||
:is(.prow-head,.prow) > .c{justify-self:center;text-align:center}
|
||||
.prows{list-style:none;margin:0;padding:0}
|
||||
.prows > .empty{border-top:var(--line) solid var(--border-subtle)}
|
||||
.prow{position:relative;min-height:var(--row-h);padding-top:10px;padding-bottom:10px;border-top:var(--line) solid var(--border-subtle);cursor:pointer;transition:background-color var(--dur-fast) var(--ease)}
|
||||
.prow:hover,.prow:focus-within{background:var(--bg-hover)}
|
||||
.prow:last-child{border-radius:0 0 var(--radius-card) var(--radius-card)}
|
||||
.prow:has(.pname:focus-visible){outline:2px solid var(--focus-ring);outline-offset:-2px}
|
||||
.prow .pt{min-width:0}
|
||||
.pname{display:block;font-weight:var(--fw-bold);color:var(--text-primary);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;outline:0}
|
||||
.prow .pname::after{content:"";position:absolute;inset:0}
|
||||
.psub{display:block;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.prow .dl b{display:block;font-weight:var(--fw-regular);white-space:nowrap}
|
||||
.prow .dl b.due-today{font-weight:var(--fw-bold)}
|
||||
.prow .dl small{display:block;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary);white-space:nowrap}
|
||||
.prow .st{display:flex;align-items:center;gap:var(--sp-2);white-space:nowrap}
|
||||
.prow .st .hint-u{position:relative;z-index:1}
|
||||
.dash{color:var(--text-secondary)}
|
||||
.nx{position:relative;z-index:1;display:inline-flex;align-items:center;gap:var(--sp-1);height:var(--control-h-sm);padding:0;border:0;background:none;font:inherit;color:var(--text-primary);white-space:nowrap;cursor:pointer;text-decoration:none}
|
||||
.nx span{text-decoration:underline;text-decoration-color:var(--link-underline);text-underline-offset:3px;transition:text-decoration-color var(--dur-fast) var(--ease)}
|
||||
.nx:hover span{text-decoration-color:var(--c-ink)}
|
||||
.nx .ic{color:var(--text-secondary);transition:transform var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
|
||||
.prow:hover .nx .ic,.prow:focus-within .nx .ic{transform:translateX(3px);color:var(--text-primary)}
|
||||
Reference in New Issue
Block a user