
/* finesse · register=product · A=warm-graphite+ember-brass · B=600/400+mono · C=sidebar-shell+bento
 * D=css-only-state-feedback · E=ledger-vault-paper · SOUL=5 SPECTACLE=2 DENSITY=7 */
.tc-root{
  --bg:#F6F4F1; --card:#FDFCFA; --sunk:#EFEAE3; --rail:#1E1A15; --rail-2:#2A251E;
  --ink:#1F1B16; --ink-2:#4A443C; --ink-3:#6D665E;
  --line:rgba(31,27,22,.09); --line-2:rgba(31,27,22,.14);
  --accent:#A85C26; --accent-ink:#FFF7EF; --accent-soft:#F4E6D8;
  --ok:#2F6B4F; --ok-soft:#E3EFE8; --warn:#8E6200; --warn-soft:#F6EDD6;
  --bad:#A63A2A; --bad-soft:#F5E2DE; --info:#3D5A6C; --info-soft:#E4EBEF;
  --r-ctl:6px; --r-card:10px; --r-panel:14px; --measure:1180px;
  /* 顶栏实际高度由 app.js 量出来写回 --toph；稿面与没脚本时用 57 */
  --toph:57px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s6:24px; --s8:32px; --s12:48px;
  --f-12:12px; --f-13:13px; --f-14:14px; --f-16:16px; --f-18:18px; --f-22:22px; --f-28:28px;
  --mono:ui-monospace,SFMono-Regular,"Cascadia Mono",Consolas,"Liberation Mono","PingFang SC","Microsoft YaHei",monospace;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  font-family:var(--sans); color:var(--ink); background:var(--bg);
  font-size:var(--f-14); line-height:1.5; -webkit-font-smoothing:antialiased;
  min-height:100vh;
}
.tc-root *,.tc-root *::before,.tc-root *::after{box-sizing:border-box}
.tc-root h1,.tc-root h2,.tc-root h3,.tc-root p,.tc-root ul,.tc-root li{margin:0;padding:0}
.tc-root ul{list-style:none}
.tc-root button{font:inherit;color:inherit;cursor:pointer;border:0;background:none}
.tc-root a{color:inherit;text-decoration:none}

.tc-view{container-type:inline-size}
/* ---------- 应用壳 ---------- */
/* 定高外壳：滚的只有右栏，侧栏和顶栏都留在原位。
   grid-template-rows 必须是 minmax(0,1fr)：自动行会按内容撑高，外壳被顶穿，滚动条就回不到面板上 */
.tc-shell{display:grid;grid-template-columns:216px minmax(0,1fr);grid-template-rows:minmax(0,1fr);height:640px;background:var(--bg)}
.tc-rail{background:var(--rail);color:#D8D0C6;padding:var(--s4) 0;display:flex;flex-direction:column;gap:var(--s1);overflow-y:auto}
.tc-brand{padding:0 var(--s4) var(--s4);display:flex;gap:var(--s2);align-items:center}
.tc-brand-i{width:26px;height:26px;border-radius:7px;background:var(--accent);color:var(--accent-ink);display:grid;place-items:center;font-size:var(--f-13);font-weight:700}
.tc-brand b{color:#F3EDE5;font-size:var(--f-14);letter-spacing:.01em;display:block}
.tc-brand>span>span{font-size:var(--f-12);color:#958C81;display:block;margin-top:1px}
.tc-nav{display:flex;flex-direction:column;gap:2px;padding:0 var(--s2)}
.tc-nav-i{display:flex;align-items:center;gap:var(--s3);padding:8px 10px;border-radius:var(--r-ctl);
  font-size:var(--f-14);color:#B4AB9F;text-align:left;width:100%}
.tc-nav-i:hover{background:var(--rail-2);color:#E7E0D6}
.tc-nav-i[aria-current=page]{background:var(--rail-2);color:#FFF;box-shadow:inset 2px 0 0 var(--accent)}
.tc-nav-i .tc-ico{width:16px;text-align:center;opacity:.85;font-size:13px}
.tc-nav-i .tc-n{margin-left:auto;font-size:var(--f-12);color:#958C81;font-family:var(--mono)}
.tc-rail-foot{margin-top:auto;padding:var(--s4);font-size:var(--f-12);color:#958C81;line-height:1.6;border-top:1px solid var(--rail-2)}
.tc-main{min-width:0;display:flex;flex-direction:column;overflow-y:auto}
/* 顶栏定高 57 = 11 + 控件 34 + 11 + 1 描边。以前高度跟着内容走：同一条里塞了输入框就顶到 59，
   什么都不放的屏又只有 50，切页面时这条线一直在跳 */
.tc-top{display:flex;align-items:center;gap:var(--s3);flex:0 0 auto;min-height:57px;position:sticky;top:0;z-index:5;padding:11px max(var(--s6),calc((100% - var(--measure))/2 + var(--s6)));border-bottom:1px solid var(--line);background:var(--card)}
.tc-top>div:first-child{display:flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap;min-width:0}
.tc-top-t{font-size:var(--f-18);font-weight:600;letter-spacing:-.01em}
.tc-top-s{font-size:var(--f-12);color:var(--ink-3)}
.tc-top-r{margin-left:auto;display:flex;align-items:center;gap:var(--s2)}
/* 顶栏里的输入框跟同一条里的按钮齐平；沿用全局的 36 会把定高那一档顶穿 */
.tc-top-r .tc-in{height:34px}
.tc-body{width:100%;max-width:var(--measure);margin-inline:auto;padding:var(--s6);display:flex;flex-direction:column;gap:var(--s8)}

/* ---------- 通用件 ---------- */
.tc-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--s4)}
.tc-sec{display:flex;flex-direction:column;min-width:0}
/* 分组节奏：组与组 32（挂在 body/flow 的 gap 上）、标题到自己卡片 12 —— 差到近三倍才看得出标题管的是下面那张 */
.tc-legend{font-size:var(--f-14);font-weight:600;color:var(--ink);margin:0 0 var(--s3);display:flex;align-items:center;gap:var(--s2)}
.tc-legend .tc-hint{font-weight:400;color:var(--ink-3);font-size:var(--f-12)}
.tc-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:34px;padding:0 14px;white-space:nowrap;
  border-radius:var(--r-ctl);font-size:var(--f-13);font-weight:600;border:1px solid var(--line-2);background:var(--card);color:var(--ink)}
.tc-btn:hover{background:var(--sunk)}
.tc-btn.pri{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.tc-btn.pri:hover{background:#94501F}
.tc-btn.ghost{background:transparent;border-color:transparent;color:var(--ink-2)}
.tc-btn.ghost:hover{background:var(--sunk)}
.tc-btn.sm{height:28px;padding:0 10px;font-size:var(--f-12)}
.tc-btn.big{height:44px;padding:0 20px;font-size:var(--f-14)}
.tc-btn.dis{opacity:.45;pointer-events:none}
.tc-chip{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 8px;border-radius:999px;white-space:nowrap;
  font-size:var(--f-12);font-weight:600;background:var(--sunk);color:var(--ink-2)}
.tc-chip.ok{background:var(--ok-soft);color:var(--ok)} .tc-chip.bad{background:var(--bad-soft);color:var(--bad)}
.tc-chip.warn{background:var(--warn-soft);color:var(--warn)} .tc-chip.info{background:var(--info-soft);color:var(--info)}
.tc-chip.acc{background:var(--accent-soft);color:#7C4318}
.tc-dot{width:6px;height:6px;border-radius:50%;background:currentColor;display:inline-block}
.tc-mono{font-family:var(--mono);font-size:var(--f-13);letter-spacing:-.01em;overflow-wrap:anywhere}
.tc-note{align-items:flex-start}
.tc-val{display:inline-flex;align-items:center;gap:var(--s2);background:var(--sunk);border-radius:var(--r-ctl);
  padding:5px 8px;font-family:var(--mono);font-size:var(--f-13);color:var(--ink);max-width:100%;overflow-wrap:anywhere}
.tc-val .tc-eye,.tc-val .tc-copy{font-size:12px;color:var(--ink-3);border-left:1px solid var(--line-2);padding-left:var(--s2)}
.tc-val .tc-eye:hover,.tc-val .tc-copy:hover{color:var(--accent)}
.tc-val-m{flex:1 1 auto;min-width:0}
.tc-val-a{display:flex;align-items:center;gap:var(--s2);flex:0 0 auto;margin-left:auto;white-space:nowrap}
.tc-row{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) 0;border-top:1px solid var(--line)}
.tc-row>.tc-t{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.tc-row:has(.tc-full){flex-wrap:wrap;align-items:flex-start}
.tc-full{flex:1 1 100%;min-width:0;overflow-wrap:anywhere}
/* 取值条单独放在卡片里时父级不是 flex，上面那条 flex:1 白写，桌面就缩成一小块；给它自己的宽度 */
.tc-val.tc-full{width:100%}
.tc-row:first-of-type{border-top:0}
/* 动作行：稿面以前在 markup 里现写 flex，真实页面走 .tc-actions —— 同一把尺子，
   不然手机上「居中」这条只落在成品，稿面还是靠左，两边看着就不是一回事 */
.tc-actions{display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap;margin-top:var(--s4)}

/* ---------- 表单 ---------- */
.tc-f{display:flex;flex-direction:column;gap:5px;padding:var(--s3) 0;border-top:1px solid var(--line)}
.tc-f:first-child{border-top:0;padding-top:0}
.tc-f-l{font-size:var(--f-13);font-weight:600;color:var(--ink)}
.tc-f-l em{font-style:normal;font-weight:400;color:var(--ink-3);font-family:var(--mono);font-size:var(--f-12)}
.tc-f-h{font-size:var(--f-12);color:var(--ink-3);line-height:1.55}
.tc-in{height:36px;border:1px solid var(--line-2);border-radius:var(--r-ctl);background:var(--card);
  padding:0 10px;font-size:var(--f-14);width:100%;color:var(--ink)}
.tc-in.mono{font-family:var(--mono);font-size:var(--f-13)}
.tc-in:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
.tc-in[readonly]{background:var(--sunk);color:var(--ink-2)}
.tc-sel{height:36px;border:1px solid var(--line-2);border-radius:var(--r-ctl);background:var(--card);padding:0 8px;font-size:var(--f-13);color:var(--ink)}
.tc-radio{display:flex;flex-direction:column;gap:var(--s2)}
.tc-radio label{display:flex;gap:var(--s3);align-items:flex-start;border:1px solid var(--line-2);border-radius:var(--r-card);
  padding:var(--s3) var(--s4);cursor:pointer;background:var(--card)}
.tc-radio label:hover{background:var(--sunk)}
.tc-radio input{margin-top:3px;accent-color:var(--accent);width:15px;height:15px;flex:0 0 auto}
.tc-radio b{font-size:var(--f-14);display:block}
.tc-radio span{font-size:var(--f-12);color:var(--ink-3);display:block;margin-top:2px}
.tc-radio label.on{border-color:var(--accent);background:var(--accent-soft)}
.tc-radio label.on b{color:#7C4318}

/* ---------- 提示条 ---------- */
.tc-note{display:flex;gap:var(--s3);padding:var(--s3) var(--s4);border-radius:var(--r-card);
  border:1px solid var(--line);background:var(--sunk);font-size:var(--f-13);line-height:1.55}
.tc-note b{font-weight:600}
.tc-note.bad{background:var(--bad-soft);border-color:rgba(166,58,42,.22);color:#7E2A1D}
.tc-note.warn{background:var(--warn-soft);border-color:rgba(154,107,0,.2);color:#6E4C00}
.tc-note.ok{background:var(--ok-soft);border-color:rgba(47,107,79,.2);color:#21503A}
.tc-note.info{background:var(--info-soft);border-color:rgba(61,90,108,.2);color:#2A4150}
.tc-note .tc-i{flex:0 0 auto;font-weight:700}

/* ---------- 首屏 ---------- */
.tc-hook{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-radius:var(--r-panel);
  background:var(--card);border:1px solid var(--line)}
.tc-hook-k{display:flex;align-items:baseline;flex-wrap:wrap;gap:var(--s1) var(--s3);
  padding:var(--s3) var(--s4);min-width:0;border-left:1px solid var(--line)}
.tc-hook-k:first-child{border-left:0}
.tc-hook-v{font-size:var(--f-18);font-weight:600;letter-spacing:-.02em;font-family:var(--mono);
  font-variant-numeric:tabular-nums;line-height:1.5;flex:0 0 auto}
.tc-hook-l{font-size:var(--f-13);color:var(--ink-3);letter-spacing:.01em}
.tc-todo{display:flex;flex-direction:column;gap:var(--s2)}
.tc-todo-a{display:flex;gap:var(--s2);margin-left:auto;flex:0 0 auto}
.tc-grid2{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:var(--s6)}
.tc-acc{display:flex;align-items:center;gap:var(--s2);font-size:var(--f-12);color:var(--ink-3);margin-top:var(--s2);flex-wrap:wrap;overflow-wrap:anywhere}
.tc-pick{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--s3)}

/* ---------- 台账 ---------- */
.tc-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:var(--s3)}
.tc-group{border:1px solid var(--line-2);border-radius:var(--r-card);padding:var(--s4);background:var(--card);text-align:left;width:100%}
.tc-group.on{border-color:var(--accent);background:var(--accent-soft)}
.tc-group-n{font-size:var(--f-22);font-weight:600;font-family:var(--mono);letter-spacing:-.02em}
.tc-group-l{font-size:var(--f-13);font-weight:600}
.tc-group-h{font-size:var(--f-12);color:var(--ink-3);margin-top:var(--s1)}
.tc-tb{width:100%;border-collapse:collapse;font-size:var(--f-13)}
.tc-filters{display:flex;gap:var(--s2);margin-bottom:var(--s3);flex-wrap:wrap}
.tc-tb th{text-align:left;font-weight:600;color:var(--ink-3);font-size:var(--f-12);padding:0 var(--s3) var(--s2);border-bottom:1px solid var(--line)}
.tc-tb td{padding:var(--s3);border-bottom:1px solid var(--line);vertical-align:middle}
.tc-tb tr:hover td{background:var(--sunk)}
.tc-tb .tc-name{font-weight:600;color:var(--ink)}
.tc-tb .tc-sub{font-size:var(--f-12);color:var(--ink-3)}
/* 勾选与批量：复选框画在「账号」那一格里，不新增一列 —— 手机卡片模式下不会多出一行只有方框的空档。
   命中区不能靠控件自己的内边距：appearance 的表单控件被强制 border-box，padding 撑不开方框，
   只能交给包着它的 label（隐式关联，点方框外一圈也算勾上），负外边距让它别多占位。
   margin:0 不是摆设：Chrome 给原生方框自带 3px 外边距，不摘掉批量条会莫名高出 6px */
.tc-box{width:20px;height:20px;margin:0;border:0;background:none;
  accent-color:var(--accent);cursor:pointer;flex:0 0 auto}
.tc-hit{display:grid;place-items:center;width:40px;height:40px;margin:-10px;cursor:pointer;flex:0 0 auto}
.tc-ck{display:inline-flex;align-items:center;gap:var(--s2);padding:var(--s2) 0;font-size:var(--f-12);color:var(--ink-2);cursor:pointer}
.tc-bulk{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s3)}
.tc-bulk .tc-btn{margin-left:auto}
.tc-bulk-n{font-size:var(--f-12);color:var(--ink-3);font-family:var(--mono)}
.tc-tb td.tc-acct{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:var(--s3)}
.tc-tb td.tc-c{display:flex;align-items:center;justify-content:flex-end;gap:var(--s2)}
/* ---- 网盘浏览：面包屑 / 目录行 / 分页条 ----
   只用上面那把尺子里已有的档（--s*、--f-*、--r-*），没为这一屏新开任何一档数值 */
.tc-crumb{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s1);font-size:var(--f-13)}
.tc-crumb-s{color:var(--ink-3)}
.tc-crumb-on{color:var(--ink);font-weight:600}
.tc-tb td.tc-file{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:var(--s3)}
.tc-file>div{min-width:0;overflow-wrap:anywhere}
.tc-fi{display:grid;place-items:center;width:24px;height:24px;border-radius:var(--r-ctl);
  background:var(--sunk);color:var(--ink-3);font-size:var(--f-12);flex:0 0 auto}
.tc-fi.d{background:var(--accent-soft);color:var(--accent)}
.tc-inline{display:inline-flex;align-items:center;gap:var(--s2)}
.tc-pager{display:flex;align-items:center;gap:var(--s3);margin-top:var(--s4);flex-wrap:wrap}
.tc-nowrap{white-space:nowrap}
/* 网格/列表那一档切换：放在分组标题右端，切视图不改筛选，两个链接都带着 dir 与 id */
.tc-seg{margin-left:auto;display:inline-flex;gap:2px;padding:2px;background:var(--sunk);border-radius:var(--r-ctl)}
.tc-seg-i{font-size:var(--f-12);color:var(--ink-3);padding:var(--s1) 10px;border-radius:5px;white-space:nowrap}
.tc-seg-i.is-on{background:var(--card);color:var(--ink);font-weight:600;box-shadow:0 1px 2px rgba(31,27,22,.10)}
/* 缩略图卡片：176 是实测出来的最小档 —— 桌面正文内宽 1132（1180 减左右 24），
   6 列正好（6×176 + 5×12 = 1116），7 列就掉到 158 以下，所以按 176 起排、由 1fr 补到 178.7。
   grid-auto-rows:1fr 是为了让每一行一样高：目录卡只有一个「打开」，文件卡有两个动作，
   不收的话纯目录那几行实测 238、带文件那几行 274，一屏里两种卡高，看着像没对齐 */
/* 网格这一档照资源管理器排：白底图标 + 名字，文件底下只有一行小字动作，没有边框、没有大按钮、不上大小与日期。
   124 是实测出来的最小档：桌面正文内宽 1132，124 起排正好 8 列（8×124 + 7×12 = 1076，余量由 1fr 补到 128.5）；
   手机另写 3 列。卡片高度从 274 收到约 143，同样一屏能多看近一倍。
   grid-auto-rows:1fr 仍要留：文件卡多一行「下载 / 直链」，不收行高两种卡就一高一低 */
.tc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(124px,1fr));grid-auto-rows:1fr;gap:var(--s2) var(--s3)}
.tc-gi{display:flex;flex-direction:column;min-width:0;text-align:center;padding:var(--s2) 2px;
  border-radius:var(--r-card);border:1px solid transparent;position:relative}
.tc-gi:hover{background:var(--sunk);border-color:var(--line)}
/* 缩略图底是白的：图标和真图都落在白底上，像资源管理器那一格 */
.tc-gthumb{display:grid;place-items:center;height:96px;background:var(--card);border-radius:var(--r-ctl);
  overflow:hidden;position:relative}
.tc-gthumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block}
/* 图标：实心彩色 SVG，颜色写在路径里；这里只管尺寸 —— 再写 fill/stroke 会把黄夹子和文档色带一起抹平 */
.tc-gico{display:grid;place-items:center;width:100%;height:100%}
.tc-gico svg{width:72px;height:72px}
/* 选网盘卡的白底格：百度放官方 App 图标加一行小字，其余网盘退回一行大字；长名省略不撑破 */
.tc-gthumb img.tc-gapp{position:static;width:52px;height:52px;display:block;object-fit:contain}
.tc-gthumb:has(.tc-gapp) .tc-gtext{font-size:13px;font-weight:500;line-height:1.2}
.tc-gtext{font-size:22px;line-height:1.15;font-weight:600;letter-spacing:.02em;color:var(--thumb-ink,#1d1b16);
  white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.tc-fi svg{width:16px;height:16px}
.tc-gcap{padding:var(--s1) 2px 0;min-width:0}
/* 名字照资源管理器换行：最多两行，超出省略；不再挤成一条省略号 */
.tc-gname{font-size:var(--f-13);font-weight:400;color:var(--ink);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}
.tc-gmeta{display:flex;flex-wrap:wrap;justify-content:center;gap:0 var(--s2);font-size:var(--f-12);color:var(--ink-3);margin-top:var(--s1)}
.tc-gmeta span{white-space:nowrap;min-width:0}
/* 选网盘的卡整张包一条链接：白底网盘标 + 名字 + 一行小字，不单摆大按钮，跟目录卡一个节奏 */
.tc-gpick{display:flex;flex-direction:column;min-width:0;color:inherit;text-decoration:none}
.tc-gpick .tc-gcap{display:block}
/* 文件的两个动作收成一行小字；文件夹没有这一行 —— 点图标就进去了 */
.tc-gact{display:flex;justify-content:center;gap:var(--s3);padding:0;margin-top:2px}
.tc-glink{font-size:var(--f-12);color:var(--accent);background:none;border:0;padding:0;line-height:18px;cursor:pointer}
.tc-glink:hover{text-decoration:underline}
/* 目录那条横栏粘在滚动口上沿：顶栏多高由脚本量进 --toph（稿面按 57），往下翻时网格在它底下走，
   选中的文件与两个动作一直看得见。没脚本时 .tc-sel 不出现、卡片上的小字动作照旧留着。
   负的 margin-top 吃掉正文顶部的内边距，让它的自然位置就等于粘住的位置 ——
   否则一开滚它会先往上滑 24 再停住，看着像会动 */
.tc-legend-bar{position:sticky;top:var(--toph,57px);z-index:8;flex-wrap:wrap;row-gap:var(--s2);
  padding:var(--s2) 0;margin:calc(-1*var(--s6)) 0 calc(var(--s3) - var(--s8));
  background:var(--bg);border-bottom:1px solid var(--line)}
.tc-bar-crumb{flex:0 1 auto;min-width:0}
.tc-bar-crumb .tc-link{color:var(--ink-2)}
.tc-bar-count{font-weight:400;font-size:var(--f-12);color:var(--ink-3);white-space:nowrap}
.tc-sel{display:none;margin-left:auto;align-items:center;gap:var(--s2);min-width:0}
.tc-js .tc-sel{display:inline-flex}
.tc-legend-bar .tc-sel+.tc-seg{margin-left:0}
.tc-selname{font-weight:400;color:var(--ink-3);font-size:var(--f-12);max-width:24ch;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tc-selact{display:inline-flex;gap:var(--s2)}
/* 有脚本才把卡片上那行小字收进横栏；没脚本它还在，下载照点 */
.tc-js .tc-grid .tc-gact{display:none}
.tc-js .tc-tb .tc-inline{display:none}
.tc-js .tc-grid .tc-gi[data-fsid]{cursor:pointer}
/* 文件右上角那颗勾：勾上之后横栏的下载/直链才可点；没脚本它不出现 */
.tc-pick-l{display:none;position:absolute;top:calc(var(--s2) - 6px);right:calc(var(--s2) - 6px);z-index:3;
  cursor:pointer;padding:6px}
.tc-js .tc-pick-l{display:inline-flex}
.tc-pick{width:18px;height:18px;margin:0;accent-color:var(--accent);cursor:pointer;border-radius:3px;
  box-shadow:0 1px 3px rgba(0,0,0,.18)}
.tc-tb .tc-pick-l{position:static;padding:0;margin-right:var(--s2)}
/* 列表档的「名称」格原本两列（图标 + 文字），多出勾选框后要补成三列，否则名字被挤到下一行 */
.tc-js .tc-tb td.tc-file{grid-template-columns:auto auto minmax(0,1fr)}
.tc-gi.is-sel{border-color:var(--accent);background:var(--accent-soft)}
.tc-tb tbody tr.is-sel td{background:var(--accent-soft)}
.tc-l-short{display:none}
/* 大图层：只在脚本起来后才出现，没脚本时卡片链接直接把真图开在新标签里。
   定位锚在 .tc-view 上（container-type 让它成为固定定位的包含块），
   成品那一层正好等于视口，稿面上等于预览帧 —— 两边同一套规则，不用各写一份 */
.tc-lb{position:fixed;inset:0;z-index:70;display:none;place-items:center;padding:0;
  /* 行高写死一整屏：图只在中间那块里缩放，不会按原比例把整层顶高 */
  grid-template-rows:minmax(0,1fr);
  /* 整窗一层，底做实心：底下那页的字不再从边条后面透出来 */
  background:#181410}
.tc-lb.is-on{display:grid}
.tc-lb-box{display:flex;flex-direction:column;gap:var(--s3);width:min(850px,100%);min-width:0}
/* 大图层是整窗的一层：上下只留标题与动作两条，图自己铺满中间 —— 不再套 850 的框 */
.tc-lb .tc-lb-box{width:100%;height:100%;gap:0}
.tc-lb .tc-lb-top{padding:var(--s3) var(--s4) 0}
.tc-lb .tc-lb-stage{flex:1 1 auto;min-height:0}
.tc-lb .tc-lb-img{height:100%;max-height:none;border-radius:0}
.tc-lb .tc-lb-foot{padding:var(--s2) var(--s4) var(--s3)}
.tc-lb-top{display:flex;align-items:baseline;gap:var(--s3);color:#E8E2DA;min-width:0}
.tc-lb-name{font-size:var(--f-14);font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tc-lb-meta{font-size:var(--f-12);color:#A79E92;flex:0 0 auto}
/* 大图层里的按钮都提到两级：.tc-root button 带一个类加标签，会把这里的字色、边框、底色压回去，
   压回去后 ‹ › 成了深褐色透明底，浮在近黑遮罩上等于看不见，只能靠键盘翻 */
.tc-lb .tc-lb-x{margin-left:auto;flex:0 0 auto;font-size:var(--f-13);color:#E8E2DA;
  padding:var(--s1) var(--s3);border:1px solid rgba(232,226,218,.28);border-radius:var(--r-ctl)}
.tc-lb-stage{display:flex;align-items:center;gap:var(--s2);min-width:0}
.tc-lb-img{flex:1 1 auto;min-width:0;max-height:min(580px,68vh);width:100%;object-fit:contain;
  border-radius:var(--r-card);background:#1E1A15}
.tc-lb .tc-lb-nav{flex:0 0 auto;width:44px;height:44px;border-radius:var(--r-ctl);font-size:var(--f-18);
  color:#E8E2DA;background:rgba(232,226,218,.12);border:1px solid rgba(232,226,218,.20)}
.tc-lb .tc-lb-nav:hover:not([disabled]){background:rgba(232,226,218,.22)}
.tc-lb .tc-lb-nav[disabled]{opacity:.32}
.tc-lb-foot{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;color:#A79E92;font-size:var(--f-12)}
.tc-lb-foot .tc-btn{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
/* 卡片上的动作收成小字之后，搬进大图层也得在深底上看清 */
.tc-lb-foot .tc-glink{color:#F3EDE5;font-size:var(--f-13);line-height:26px}
/* 大图层里那条下载表单是从卡片上整条搬过来的，两个动作在这条里要横着排 */
.tc-lb-foot form{display:inline-flex;gap:var(--s2)}
/* 图层开着的时候右栏别再跟着滚：由壳自己找出那一层，稿面与成品同一个条件 */
.tc-view:has(.tc-lb.is-on) .tc-main{overflow:hidden}
.tc-btn.danger{color:var(--bad);border-color:rgba(166,58,42,.26)}
.tc-btn.danger:hover{background:var(--bad-soft)}
/* 行尾那颗跟同组的实心按钮分轻重：只留字色，边框和底都交回给 ghost */
.tc-btn.ghost.danger{background:transparent;border-color:transparent}
.tc-btn.ghost.danger:hover{background:var(--bad-soft)}
.tc-btn.danger.pri{background:var(--bad);border-color:var(--bad);color:#FFF4F1}
.tc-btn.danger.pri:hover{background:#8C2F22}

/* ---------- 取 token 流程 ---------- */
.tc-flow{display:flex;flex-direction:column;gap:var(--s8);width:100%}
/* 码这块自己一列：码、过期行、轮询状态从上到下居中，不再和说明挤同一排 */
.tc-qrbox{display:flex;flex-direction:column;align-items:center;gap:var(--s3)}
.tc-qr{width:232px;height:232px;padding:12px;background:var(--card);border:1px solid var(--line-2);border-radius:var(--r-card)}
.tc-qr canvas{width:100%;height:100%;display:block;image-rendering:pixelated}
.tc-poll{display:flex;align-items:center;gap:var(--s2);font-size:var(--f-13);color:var(--warn)}
.tc-spin{width:12px;height:12px;flex:0 0 auto;border:2px solid var(--warn);border-top-color:transparent;border-radius:50%;animation:tcsp .8s linear infinite}
@keyframes tcsp{to{transform:rotate(360deg)}}
/* 过期行不再自带 margin-top：它只在 .tc-qrbox 里出现，间距由那条列的 gap 给 */
.tc-expire{font-size:var(--f-12);color:var(--ink-3);font-family:var(--mono)}

/* ---------- 空状态 ---------- */
/* 一屏一个度量：外框收到 640，说明、步骤、提示都吃满同一条内宽，不再各写各的 max-width */
.tc-empty{max-width:640px;margin-inline:auto;border:1px dashed var(--line-2);border-radius:var(--r-panel);
  padding:var(--s8) var(--s6);text-align:center;background:linear-gradient(180deg,#FBF9F6,#F2EEE8)}
.tc-empty-h{font-size:var(--f-18);font-weight:600;letter-spacing:-.01em}
/* 这一段的 p / ul / li 会被上面的全局复位打掉边距与内缩，所以带 .tc-root 提权；
   稿面 markup 和 lib/ui.mjs 的 empty() 必须同构，不然这种坑只在一边露出来 */
.tc-root .tc-empty-p{font-size:var(--f-13);color:var(--ink-3);margin:var(--s1) auto 0;line-height:1.6}
.tc-root .tc-how{list-style:none;display:grid;gap:var(--s3);margin:var(--s6) 0 0;padding:0;text-align:left}
.tc-root .tc-how-i{display:flex;gap:var(--s3);align-items:flex-start;background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-card);padding:var(--s3) var(--s4)}
.tc-how-b{width:22px;height:22px;border-radius:50%;background:var(--accent-soft);color:#7C4318;
  display:grid;place-items:center;font-size:var(--f-12);font-weight:700;flex:0 0 auto;font-family:var(--mono)}
.tc-how-t{flex:1 1 auto;min-width:0;font-size:var(--f-13)}
.tc-how-t b{display:block;font-size:var(--f-14);margin-bottom:var(--s1)}
.tc-how-t span{color:var(--ink-3)}
/* 提示里的回调地址：整串 URL 没有断行点，min-content 259px 会把 320 的屏顶宽，必须允许任意断行；
   地址和「复制这一条」自成一行，不然窄屏上按钮会被甩到第三行了无着落 */
.tc-how-m{font-family:var(--mono);color:var(--ink-2);overflow-wrap:anywhere}
.tc-how-cb{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center;margin-top:var(--s2)}
/* 嵌在卡片里的小空态另算：虚线框铺满卡片（卡片本身就是收口，再套 640 就两头空着，
   下面那条通栏提示也对不上），只把里面的文字列按同一条 590 收住 */
.tc-card>.tc-empty{max-width:none}
.tc-card>.tc-empty .tc-empty-p{max-width:590px;margin-inline:auto}


/* ---------- 前端页（访客页，不属于后台） ---------- */
.tc-shell-fe{grid-template-columns:minmax(0,1fr)}
.tc-shell-fe .tc-main{max-width:760px;margin:0 auto;width:100%}
/* 前端四屏的壳：窄屏一列按 轨 → 正文 → 要点 → 动作条 排，宽屏把要点甩到右栏。
   动作条是 .tc-fe 的最后一个子项，手机上 margin-top:auto 才钉得住、宽屏它落在左栏下面不被右栏顶走 */
.tc-fe{display:flex;flex-direction:column;gap:var(--s8);min-width:0}
.tc-col{display:flex;flex-direction:column;gap:var(--s8);min-width:0}
.tc-side{display:flex;flex-direction:column;gap:var(--s6);min-width:0}
/* 三步的轨：DOM 只有一份，窄屏和宽屏都是横排在最上面，差别只在宽屏它单独占满一整行 */
.tc-trail{display:flex;align-items:center;gap:var(--s2);font-size:var(--f-12);color:var(--ink-3)}
.tc-trail .tc-ti{display:flex;align-items:center;gap:6px}
.tc-trail .tc-ti.on{color:var(--ink);font-weight:600}
.tc-trail .tc-b{width:18px;height:18px;border-radius:50%;background:var(--sunk);color:var(--ink-3);
  display:grid;place-items:center;font-size:var(--f-12);font-weight:700;font-family:var(--mono)}
.tc-trail .tc-ti.on .tc-b{background:var(--accent);color:var(--accent-ink)}
.tc-trail .tc-tl{flex:0 0 auto;width:28px;height:1px;background:var(--line-2)}
/* 三条退路拆成三行：一行一个说法、一个控件，控件跟在自己那句下面，不再四个挤同一排 */
.tc-way{display:flex;gap:var(--s3);align-items:flex-start;padding:var(--s4) 0;border-top:1px solid var(--line)}
.tc-way:first-child{border-top:0;padding-top:0}
.tc-way:last-child{padding-bottom:0}
.tc-way-a{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center;margin-top:var(--s2)}
.tc-way-a .tc-in{flex:1 1 220px;min-width:0}
/* 卡片开头就是说明或动作时别再叠一次上边距：省掉成品里那几条行内 style="margin-top:0" */
.tc-card>.tc-quiet:first-child,.tc-card>.tc-actions:first-child{margin-top:0}
.tc-drives{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--s3)}
.tc-drive{display:flex;align-items:center;gap:var(--s3);border:1px solid var(--line-2);border-radius:var(--r-card);
  padding:var(--s3);background:var(--card);text-align:left;cursor:pointer}
.tc-drive-i{width:30px;height:30px;border-radius:8px;background:var(--sunk);display:grid;place-items:center;
  font-size:13px;font-weight:700;flex:0 0 auto;color:var(--ink-2)}
.tc-drive b{font-size:var(--f-14);display:block;color:var(--ink)}
.tc-drive-s{font-size:var(--f-12);color:var(--ink-3);display:block;margin-top:2px}
.tc-drive.on{border-color:var(--accent);background:var(--accent-soft)}
.tc-drive.on .tc-drive-i{background:var(--accent);color:var(--accent-ink)}
.tc-drive.off{opacity:.42;cursor:not-allowed}
.tc-fe-foot{padding:var(--s4);font-size:var(--f-12);color:var(--ink-3);text-align:center;line-height:1.7;
  border-top:1px solid var(--line)}
.tc-res{display:flex;align-items:center;gap:var(--s3);font-size:var(--f-18);font-weight:600;letter-spacing:-.01em}
.tc-res .tc-chip{flex:0 0 auto}
.tc-quiet{font-size:var(--f-13);color:var(--ink-3);line-height:1.65;margin-top:var(--s2)}
/* 1000 以上才分两栏：正文一栏 + 300 的要点栏。整壳收到 1040，左栏落到 660 上下，
   和后台 1180 内宽是同一条尺感，不是把两栏硬塞进原来那条 640 */
@container (min-width:1000px){
  .tc-shell-fe .tc-main{max-width:1040px}
  .tc-fe.is-2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,300px);gap:var(--s8);align-items:start}
  /* 轨单独占满第一行：不写这条，自动排版会把它塞进右栏那条 300 的窄列里断行 */
  .tc-fe.is-2>.tc-trail{grid-column:1/-1}
  /* 精简档没有要点栏，就真是单栏：按可读宽度收住居中，不留一条空列。
     width 必须自己写：flex 子项带 auto 外边距时不再拉伸，只给 max-width 会缩成内容宽（实测 244） */
  .tc-fe.is-1{width:min(100%,668px);margin-inline:auto}
}
@container (max-width:560px){
  .tc-drives{grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}
  .tc-res{font-size:var(--f-16)}
}

/* ---------- 手机底栏 ---------- */
.tc-tabbar{display:none}
/* 窄桌面（约 1024 的窗口）：表格挤到一字一行之前，先让它自己横向滚 */
@container (max-width:1000px){
  .tc-card:has(.tc-tb){overflow-x:auto}
  .tc-tb{min-width:680px}
}
@container (max-width:560px){
  .tc-shell{grid-template-columns:minmax(0,1fr)}
  .tc-rail{display:none}
  /* 57 那一档是给桌面的：手机顶栏会换成两行，定高只会在标题行下面多出空白，放开让它跟着内容走 */
  .tc-top{padding:var(--s3) var(--s4);min-height:0}
  .tc-top-t{font-size:var(--f-16)}
  .tc-top-s{display:none}
  /* 目录屏顶栏没有标题了，账号这行得留着，不然左边一片空 */
  .tc-top-t .tc-top-s{display:block}
  .tc-body{padding:var(--s4);gap:var(--s6)}
  /* 正文内边距在这档收到 16，横栏的负 margin 跟着换，否则自然位置会差 8 */
  .tc-legend-bar{margin-top:calc(-1*var(--s4))}
  /* 底栏在外壳之外钉住，不再压着正文，正文不用留 76 的空档。
     前端不渲染底栏，内容不满一屏时让正文这一列撑满，底部操作条才有地方落，不然按钮悬在半屏下面。
     壳是 .tc-fe；选方式那屏整页一个表单，表单套在壳外面，所以两级都要撑满 */
  .tc-shell-fe .tc-body{flex:1 1 auto}
  .tc-shell-fe .tc-body>.tc-form,.tc-shell-fe .tc-body>.tc-fe,.tc-shell-fe .tc-form>.tc-fe{flex:1 1 auto}
  .tc-shell-fe .tc-sticky{margin-top:auto}
  .tc-fe,.tc-col{gap:var(--s6)}
  .tc-side{gap:var(--s4)}
  .tc-grid2{grid-template-columns:minmax(0,1fr)}
  .tc-hook{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tc-hook-k{flex-direction:column;align-items:flex-start;gap:var(--s1);padding:var(--s2) var(--s4);
    border-left:0;border-top:1px solid var(--line)}
  .tc-hook-k:nth-child(2n){border-left:1px solid var(--line)}
  .tc-hook-k:nth-child(-n+2){border-top:0}
  .tc-btn{height:40px;padding:0 14px}
  .tc-btn.big{width:100%}
  /* 手机上的点按区：控件 44 高，字号 16 —— 低于 16 输入框一聚焦，手机浏览器就整页放大 */
  .tc-in,.tc-sel{height:44px;font-size:var(--f-16)}
  .tc-in.mono{font-size:var(--f-16)}
  .tc-btn.sm{height:36px;padding:0 12px}
  .tc-val .tc-eye,.tc-val .tc-copy{display:inline-flex;align-items:center;min-height:36px;padding:0 4px}
  .tc-filters{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s2)}
  .tc-filters .tc-sel{width:100%}
  .tc-qr{width:172px;height:172px}
  /* 过期行会宽于码（172），align-items:center 只把项收到内容宽，
     窄屏上它一断行就贴着左边歪 —— 文本自己居中才和屏中对齐 */
  .tc-expire{text-align:center}
  /* 前端那几屏的动作行手机上居中：退路每一行的控件走 .tc-way-a，中转屏和结果屏走 .tc-actions；
     后台的动作行继续靠左，它们要跟表格的列对齐 */
  .tc-shell-fe .tc-actions,.tc-shell-fe .tc-way-a{justify-content:center}
  /* 退路行的控件住在文本列里，文本列被 22 的编号 + 12 的间距顶右 34：
     只居中，基准是文本列，按钮比屏中偏右 17，和上面那张码不在一条中轴上。
     负 margin 把这一行的盒子拉回卡片内容左沿 —— auto 宽度自己补上 34，右沿仍停在卡片内容右沿，不溢出 */
  .tc-shell-fe .tc-way-a{margin-left:calc(-1 * (22px + var(--s3)))}
  .tc-tb thead{display:none}
  .tc-tb,.tc-tb tbody,.tc-tb tr,.tc-tb td{display:block;width:100%;min-width:0}
  .tc-tb tr{border:1px solid var(--line);border-radius:var(--r-card);background:var(--card);padding:var(--s2) var(--s3);margin-bottom:var(--s2)}
  .tc-tb td{border:0;padding:2px 0;display:flex;justify-content:space-between;gap:var(--s3);align-items:center}
  .tc-tb td::before{content:attr(data-l);font-size:var(--f-12);color:var(--ink-3)}
  .tc-tb td.tc-c{justify-content:flex-end}
  .tc-tb td[data-l=""]::before,.tc-tb td.no-l::before{display:none}
  /* 手机上写死 3 列（auto-fill 在这个宽度只会给 2 列）：图标 44、白底缩略格 64 高，
     一行三张、一屏能看四行多 */
  .tc-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s2)}
  /* 横栏在手机上换两行：上面文字与网格/列表，下面选中的名字与两颗按钮 */
  .tc-legend-bar .tc-sel{order:3;flex:1 1 100%;margin-left:0}
  .tc-legend-bar .tc-sel+.tc-seg{margin-left:auto}
  .tc-selname{flex:1 1 auto;max-width:none}
  .tc-gthumb{height:64px}
  .tc-gico svg{width:44px;height:44px}
  .tc-gtext{font-size:15px}
  .tc-gthumb img.tc-gapp{width:34px;height:34px}
  .tc-gthumb:has(.tc-gapp) .tc-gtext{font-size:11px}
  .tc-gcap{padding:var(--s1) 2px 0}
  /* 手机上顶栏放不下两枚按钮：网盘浏览留「换一条网盘」，「凭证在这里」回台账也能找到 */
  .tc-only-desk{display:none}
  /* 网盘浏览那行说明在手机上会跟位置、网格/列表挤成三行，图例只留位置与这一层的条数 */
  .tc-hint-b{display:none}
  /* 动作本来就是一行小字，手机上只把间距收一档 */
  .tc-gact{gap:var(--s2)}
  .tc-lb .tc-lb-top,.tc-lb .tc-lb-foot{padding-inline:var(--s3)}
  .tc-lb .tc-lb-foot{padding-bottom:max(var(--s3),env(safe-area-inset-bottom))}
  .tc-sticky{position:sticky;bottom:0;background:var(--card);border-top:1px solid var(--line);
    margin:0 calc(-1*var(--s4)) calc(-1*var(--s4));padding:var(--s3) var(--s4);display:flex;gap:var(--s2);z-index:6}
  /* 底栏收成一轮：三个按钮各占整宽会叠成三行，把小半屏吃掉 */
  .tc-sticky>.tc-btn{flex:1 1 auto;width:auto}
  .tc-tabbar{display:grid;grid-template-columns:repeat(5,1fr);background:var(--card);
    border-top:1px solid var(--line);padding-bottom:20px;position:relative;z-index:8}
  .tc-tabbar b{display:flex;flex-direction:column;align-items:center;gap:3px;padding:8px 0;font-size:12px;font-weight:400;color:var(--ink-3)}
  .tc-tabbar b .tc-ico{font-size:16px}
  .tc-tabbar b[aria-current=page]{color:var(--accent);font-weight:600}
  .tc-flow{gap:var(--s6)}
  .tc-pick{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tc-groups{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
  .tc-groups>*:nth-child(3):last-child{grid-column:1/-1}
  .tc-group-n{font-size:18px;line-height:22px}
  .tc-empty{padding:var(--s6) var(--s4);text-align:left}
  .tc-empty-h{font-size:var(--f-16)}
  .tc-root .tc-empty-p{margin:var(--s1) 0 0}
  .tc-root .tc-how{margin:var(--s4) 0 0}
  .tc-top{flex-wrap:wrap;row-gap:var(--s2)}
  .tc-top>div:first-child{flex:1 1 auto;min-width:0}
  .tc-top-r{flex:1 1 auto;min-width:0;margin-left:0;order:2;justify-content:flex-end}
  .tc-top-r .tc-in{flex:1 1 0;min-width:0;width:auto!important;height:44px}
  .tc-val{display:flex;gap:6px;min-width:0}
  .tc-val .tc-eye,.tc-val .tc-copy{white-space:nowrap}
  .tc-val-m{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
  .tc-val-a{margin-left:auto;flex:0 0 auto}
  .tc-row>.tc-t{display:block;min-width:0;flex:1 1 150px}
  .tc-row>.tc-t:only-child{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3)}
  .tc-row>.tc-t:only-child .tc-acc{margin-top:0;text-align:right}
  .tc-row{gap:var(--s2) var(--s3);flex-wrap:wrap}
  /* 「状态牌后面还跟着操作」的行（网盘与秘钥清单）才收成尾巴一行：52 = 名字牌 40 + 间距 12，
     让标题那一格先把首行占满，状态牌就必然跟按钮一起换到第二行，状态靠左、操作靠右贴卡片边。
     不这么定，三行的「去配」落在三个不同的 x 上，看着就是错位。
     只写「没开」没有按钮的行不进这个条件 —— 不然一颗孤零零的状态牌会被挤到第二行去 */
  .tc-row:has(.tc-t + .tc-chip + .tc-btn)>.tc-t{flex-basis:calc(100% - 52px)}
  .tc-row:has(.tc-t + .tc-chip + .tc-btn)>.tc-chip:not(:first-child){margin-right:auto}
}
/* ≈320 的窄屏：2×2 会把「最近一次写入 · 成功」挤成两行，改单列 */
@container (max-width:320px){
  .tc-hook{grid-template-columns:minmax(0,1fr)}
  .tc-hook-k:nth-child(2n){border-left:0}
  .tc-hook-k:nth-child(-n+2){border-top:1px solid var(--line)}
  .tc-hook-k:first-child{border-top:0}
  /* 3 列到这里只剩 88 宽，名字一个都放不下：收成 2 列 */
  .tc-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
.tc-toast{position:fixed;left:50%;bottom:28px;transform:translate(-50%,12px);background:var(--rail);color:#F0EAE1;
  font-size:var(--f-13);padding:9px 16px;border-radius:999px;opacity:0;pointer-events:none;transition:.18s;z-index:60}
.tc-toast.on{opacity:1;transform:translate(-50%,0)}

/* ---------- 真实页面补充（稿面上不需要，跑起来才有） ---------- */
/* 稿面把这条重置写在预览外框那一段里，抽取时被剔掉了，真实页面必须自己补上 */
html,body{margin:0;padding:0}
html{background:#F6F4F1} /* 和 --bg 同值，只能写死：令牌挂在 .tc-root 上，够不着 html */
.tc-root{min-height:100vh;min-height:100dvh}
/* 外壳按视口定高，滚动只发生在右栏里：侧栏与顶栏都不跟着走 */
.tc-view{display:flex;flex-direction:column;height:100vh;height:100dvh}
/* 稿面那条 height:640px 是给预览帧用的定高窗口；真实页面换成吃满余量。
   flex-basis 必须收 0：留着 640 当基准，矮窗口（手机地址栏一收，100vh 比可视区还高）
   就会把外壳顶出屏幕，多出来那一截让整页又能上下抖 */
.tc-shell{flex:1 1 0;min-height:0;height:auto}
/* 稿面与成品的空态 markup 现在同构（p / ol / li），复位由稿面那段 .tc-root 规则一起压住，
   这里不再补打补丁；只留真实页面独有的那条：回调提示在稿面是行内样式，成品走类名 */
.tc-root .tc-empty>.tc-note{margin:var(--s6) 0 0;text-align:left}
.tc-form{display:flex;flex-direction:column}
/* 表单为了提交把几段分组包在一层里（设置、秘钥），排版上它不该是一层：节奏跟着父级的 gap 走，
   不然组与组之间塌成 0，分组标题就贴到上一张卡片的下沿，看不出管的是上面还是下面 */
.tc-body>.tc-form,.tc-flow>.tc-form{gap:inherit}
/* 表单为了提交必须包住控件，但排版上它不该是一层：这些地方让表单透明，控件直接交给父级排 */
.tc-top-r form,.tc-sticky form,.tc-val form,.tc-row form,.tc-todo-a form,.tc-actions form,.tc-way-a form{display:contents}
/* .tc-actions 本体已经回到源稿的通用件那一段（稿面的 f2 f3 也用它），这里不再重复一份；
   只有一个动作行的表单要把它自带的 16 归零：父级给了 32 的节距，
   再叠上 16 就成了 48 —— 比同屏其他节距多半档，按钮看着像掉下去了 */
.tc-body>.tc-form>.tc-actions{margin-top:0}
.tc-sticky{display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap;padding-top:var(--s4);border-top:1px solid var(--line)}
.tc-full{flex:1 1 100%;min-width:0}
.tc-mt2{margin-top:var(--s2)}
.tc-mt3{margin-top:var(--s3)}
.tc-mt4{margin-top:var(--s4)}
.tc-qr{display:grid;place-items:center;overflow:hidden}
.tc-qr img{display:block;image-rendering:pixelated;max-width:100%;height:auto}
.tc-qr svg{display:block;width:100%;height:100%}
.tc-qr a{display:grid;place-items:center;width:100%;height:100%;font-size:var(--f-12);color:var(--ink-3);text-align:center;padding:var(--s3)}
.tc-flash{border:1px solid var(--line);border-radius:var(--r-card);padding:var(--s3) var(--s4);background:var(--sunk);font-size:var(--f-13)}
.tc-flash.ok{background:var(--ok-soft);border-color:rgba(47,107,79,.2);color:#21503A}
.tc-flash.bad{background:var(--bad-soft);border-color:rgba(166,58,42,.22);color:#7E2A1D}
.tc-link{color:var(--accent);text-decoration:underline;text-underline-offset:2px}
.tc-skip{position:absolute;left:-9999px;top:0}
.tc-skip:focus{left:var(--s4);top:var(--s4);z-index:60;background:var(--card);padding:8px 12px;border-radius:var(--r-ctl)}
/* 稿面用裸 <b> 表达「这一格」，真实页面每格是一个链接：字号颜色仍挂在 <b> 上，选中态跟着 <a> 走 */
.tc-tabbar a{display:block;-webkit-tap-highlight-color:transparent}
.tc-tabbar a[aria-current=page] b{color:var(--accent);font-weight:600}
/* 网盘、授权方式在稿面是画出来的选中态，真实页面是 radio：选中/聚焦由 :has() 顶上去，不靠类名 */
.tc-drive{cursor:pointer;position:relative}
.tc-drive input{position:absolute;opacity:0;width:1px;height:1px}
.tc-drive:has(input:checked){border-color:var(--accent);background:var(--accent-soft)}
.tc-drive:has(input:checked) .tc-drive-i{background:var(--accent);color:var(--accent-ink)}
.tc-drive:has(input:disabled){opacity:.42;cursor:not-allowed}
.tc-drive:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}
.tc-radio label:has(input:checked){border-color:var(--accent);background:var(--accent-soft)}
.tc-radio label:has(input:checked) b{color:#7C4318}
.tc-radio label:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}
.tc-root a:focus-visible,.tc-root button:focus-visible,.tc-root summary:focus-visible,
.tc-root select:focus-visible,.tc-root textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* 底栏是 .tc-view 的最后一个 flex 子项，外壳定高后天然贴在屏底，不用再 sticky 抢位置。
   稿面留的 20 是假的安全区，真实页面按手机实际的来 */
@container (max-width:560px){
  .tc-tabbar{padding-bottom:max(0px,env(safe-area-inset-bottom))}
}
/* 真值比稿面上的占位串长：手机宽度上 32 位的 key 会切掉尾巴，等宽输入收一档字号才看得全 */
@container (max-width:420px){ .tc-in.mono{font-size:var(--f-12)} }
@media print{
  .tc-rail,.tc-top-r{display:none}
  /* 定高外壳是屏幕上的规则，打印得还给纸张走自然流：不放开的话整页被框在一屏高里，
     台账这种多屏内容印出来只剩第一屏 */
  .tc-view{height:auto}
  .tc-shell{height:auto;grid-template-rows:auto}
  .tc-main,.tc-rail{overflow:visible}
  .tc-top{position:static}
}
