
:root{
  --bg:#12100e; --bg-panel:#1b1815; --bg-soft:#221e1a; --bg-strong:#2c2620;
  --line:#3a332b;
  --ink:#e8e0d2; --ink-dim:#a2988a; --ink-faint:#6f6659;
  --accent:#b8874a; --accent-soft:#d6a765;
  --water:#2f7385; --water-lit:#7fd3e4;
  --radius:10px;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
  font-family:"Noto Serif SC","Songti SC","Source Han Serif SC",Georgia,serif;
  line-height:1.6;-webkit-font-smoothing:antialiased}
.wrap{max-width:1180px;margin:0 auto;padding:26px 20px 72px}

/* 导航 */
.nav{background:var(--bg-soft);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:9}
.nav-inner{max-width:1180px;margin:0 auto;padding:0 20px;display:flex;gap:4px;overflow-x:auto}
/* 字号跟着视口收：五个链接在 30px 下要 812px 宽，窗口比这窄就会让导航
   自己冒出一条横向滚动条（画在它盒子的底边，也就是链接正下方）。
   用 clamp 让它在窄窗口自动缩到放得下，够宽时仍是定好的 30px。 */
.nav a{padding:12px 14px;color:var(--ink-dim);text-decoration:none;
  font-size:clamp(16px,3.2vw,30px);
  letter-spacing:.08em;white-space:nowrap;border-bottom:2px solid transparent}
.nav a:hover{color:var(--ink)}
.nav a.on{color:var(--accent-soft);border-bottom-color:var(--accent)}
/* 编辑版才有的那两个钮：保存 / 生成表格。挤到最右边，和五个链接拉开距离。
   nav-inner 会横向滚动，钮跟着滚——窄屏时链接本来就得滚，钮排在末尾正好 */
.nav-tools{display:flex;align-items:center;gap:6px;margin-left:auto;padding-left:14px}
.nav-btn{font:inherit;font-size:18px;letter-spacing:.06em;color:var(--ink-dim);
  background:var(--bg-soft);border:1px solid var(--line);border-radius:8px;
  padding:9px 18px;cursor:pointer;white-space:nowrap}
.nav-btn:hover:not(:disabled){border-color:var(--accent);color:var(--ink);
  background:rgba(184,135,74,.08)}
/* 没什么可保存时看得出来是灰的，别点了没反应 */
.nav-btn:disabled{opacity:.42;cursor:default}

header.sheet-head{border-bottom:2px solid var(--accent);padding-bottom:18px;margin-bottom:28px}
.eyebrow{letter-spacing:.35em;font-size:12px;color:var(--accent);text-transform:uppercase;margin:0 0 6px}
h1{margin:0;font-size:clamp(28px,5vw,44px);letter-spacing:.06em}
h1 .unnamed{color:var(--ink-faint);font-style:italic}
.ref-head{border-bottom:2px solid var(--accent);margin-bottom:20px;padding-bottom:12px}
.ref-head h1{font-size:clamp(24px,4vw,34px)}
.page-sub{color:var(--ink-dim);font-size:14px;margin:8px 0 0}
.meta-row{display:flex;flex-wrap:wrap;gap:10px 22px;margin-top:14px}
.meta{display:flex;gap:8px;align-items:baseline;font-size:14px}
.meta-k{color:var(--ink-faint);letter-spacing:.1em}

section{margin-top:36px}
h2{font-size:17px;letter-spacing:.22em;color:var(--accent-soft);margin:0 0 14px;
  padding-bottom:8px;border-bottom:1px solid var(--line);font-weight:600}
.note{color:var(--ink-dim);font-size:13px;margin:10px 0 0}
.empty{color:var(--ink-faint);font-size:13px;font-style:italic}

/* 属性表 + 雷达图 */
/* 6.55 : 4.65 = 表格 655 : 雷达 465（正文 1140 去掉 20 的间距）。表格要等比变宽，
   横向空间只能从雷达图那边匀；雷达自己还有 max-width:460 兜着 */
.attr-panel{display:grid;gap:20px;grid-template-columns:minmax(300px,6.55fr) minmax(240px,4.65fr);
  align-items:center}
/* 悬停提示：属性格子上显示表里那句"你的角色可能……" */
.tip{position:relative;display:inline-block;cursor:help;outline:none}
.tip::after{content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 9px);
  transform:translateX(-50%);background:#2a241d;border:1px solid var(--accent);
  color:var(--ink);padding:10px 15px;border-radius:8px;font-size:18px;font-weight:400;
  line-height:1.4;white-space:nowrap;letter-spacing:.02em;
  box-shadow:0 6px 18px rgba(0,0,0,.55);pointer-events:none;z-index:5;
  opacity:0;visibility:hidden;transition:opacity .12s;
  /* 没悬停时缩成 0 宽：气泡比属性格子宽得多（最长那条 318px），
     窄屏上它虽然看不见，却照样把页面撑出几 px 的横向滚动 */
  overflow:hidden;max-width:0}
.tip:hover::after,.tip:focus::after{overflow:visible;max-width:none}
.tip::before{content:"";position:absolute;left:50%;bottom:calc(100% + 4px);
  transform:translateX(-50%);border:5px solid transparent;border-top-color:var(--accent);
  pointer-events:none;z-index:5;opacity:0;visibility:hidden;transition:opacity .12s}
.tip:hover::after,.tip:hover::before,
.tip:focus::after,.tip:focus::before{opacity:1;visibility:visible}

/* 不裁剪：一裁剪提示气泡就会被切掉；表格太宽时让页面横滚 */
.attr-scroll{overflow:visible}
.attr-table{border-collapse:collapse;width:100%;min-width:300px;border:2px solid var(--line)}
/* 整张表是原版（15 / 11 / 27px、内边距 15×6、列宽 11% / 22%、表格 546 宽）
   等比放大 1.2 倍来的：字号、内边距、表格宽度**一起**乘 1.2，宽高比（2.56）才和原版一样。
   只放大字号不放大表格宽度的话，每行相对变高，整张表看着发胖。 */
.attr-table th,.attr-table td{border:1px solid var(--line);text-align:center;padding:18px 7.2px}
/* 列宽写百分比，跟着表格宽度一起放大，三列的比例就和原版一致 */
.attr-table .a-label{background:var(--bg-soft);color:var(--ink-dim);font-weight:600;
  width:11%;line-height:1.25;font-size:18px}
.attr-table .a-cn{display:block}
.attr-table .a-en{display:block;font-size:13.2px;letter-spacing:.12em;color:var(--ink-faint)}
.attr-table .a-num{background:var(--bg-panel);font-size:32.4px;font-weight:700;
  color:var(--accent-soft);width:22%;font-variant-numeric:tabular-nums}
/* 表底下「总点数」那行跟着一起放大，真正生效的那条在文件末尾的
   `.page-index .attr-side .note`（那边选择器更具体，写在这儿会被它压过去） */

.radar-fig{margin:0;width:100%;max-width:460px;justify-self:center}
.radar{width:100%;height:auto;display:block}
.r-ring{fill:none;stroke:var(--line);stroke-width:1}
.r-axis{stroke:var(--line);stroke-width:1}
.r-tick{fill:var(--ink-faint);font-size:10px;text-anchor:end;
  font-family:system-ui,sans-serif;font-variant-numeric:tabular-nums}
.r-area{fill:rgba(184,135,74,.34);stroke:var(--accent-soft);stroke-width:2;
  stroke-linejoin:round}
.r-dot{fill:var(--accent-soft);stroke:var(--bg);stroke-width:2;transition:r .12s}
/* 顶点才 3.5 半径，鼠标很难压住，外面套一个看不见的大圆当热区 */
.r-pt{cursor:help}
.r-hit{fill:transparent}
.r-pt:hover .r-dot{r:6}
.r-label{fill:var(--ink-dim);font-size:12px}
.r-label-en{fill:var(--ink-faint);font-size:10px;letter-spacing:.1em}
.r-label-v{fill:var(--accent-soft);font-size:13px;font-weight:700}
.radar-fig figcaption{color:var(--ink-faint);font-size:12px;text-align:center;margin-top:-6px}

.stat-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(148px,1fr))}
.stat{background:var(--bg-soft);border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:var(--radius);padding:10px 12px}
.stat-k{font-size:11px;letter-spacing:.14em;color:var(--ink-dim)}
.stat-v{font-size:15px;color:var(--ink);font-variant-numeric:tabular-nums}
.stat-v .big{font-size:26px;font-weight:700;color:var(--ink)}
.stat-v .slash{color:var(--ink-faint);margin:0 4px}
.stat-note{font-size:12px;color:var(--ink-faint);margin-top:2px}

/* 资产抬头。信用评级是源头，右边四项是它推出来的，主次靠位置和那条竖线分，
   所以整条是一个盒子，不是五个一样的格子。数值排版沿用属性表那套
   （小号大字距的标签 + 大号 tabular 数字），别处不用另学一套。 */
.asset-head{display:grid;grid-template-columns:auto 1fr;gap:0 24px;align-items:center;
  margin-top:14px;background:var(--bg-soft);border:3px solid var(--accent);
  border-radius:var(--radius);padding:14px 18px}
/* 卡上信用评级没写成「普通/困难/极难」时左边那块不出现，右边独占整行 */
.asset-head.ah-nocr{grid-template-columns:1fr}
.ah-k{display:block;font-size:12px;letter-spacing:.14em;color:var(--ink-dim);
  white-space:nowrap}
.ah-k i{display:block;font-style:normal;font-size:10px;letter-spacing:.16em;
  color:var(--ink-faint);margin-top:1px}
.ah-cr{padding-right:24px;border-right:1px solid var(--line)}
/* 只摆当前值一个数，所以这里给得起字号——它是整节的锚 */
.ah-crv{display:block;font-size:48px;font-weight:700;
  color:var(--accent-soft);font-variant-numeric:tabular-nums;
  line-height:1.05;margin-top:2px;letter-spacing:-.01em}
/* 四个派生值摊开占满右半边，别都挤在左侧 */
.ah-figs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px 20px}
/* 左边那块不出现时，信用评级挤进来变五个 */
.ah-nocr .ah-figs{grid-template-columns:repeat(5,minmax(0,1fr))}
.ah-fig b{display:block;font-size:22px;font-weight:700;
  color:var(--ink);font-variant-numeric:tabular-nums;margin-top:4px;line-height:1.2}
/* 生活水平是这一栏的结论，不是数字，用金色标出来 */
.ah-fig.ah-level b{font-weight:600;color:var(--accent-soft)}
.ah-u{font-style:normal;font-size:.56em;font-weight:400;color:var(--ink-faint);
  margin:0 1px;vertical-align:.1em}

/* 结算行：整节唯一的结算数，排版跟抬头一样。上面压一条线、数字靠右——
   跟表格的「价值」那一列对齐，账本里合计就是这么收的。 */
.asset-sum{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:flex-end;
  gap:10px 34px;margin:14px 0 0;padding-top:12px;border-top:1px solid var(--line)}
.asset-sum .ah-fig{text-align:right}
.asset-sum .ah-fig b{font-size:22px}
/* 单位不是结算数，甩到最左边。整行是 flex-end 收底的，它只有一行字，
   跟着收底就会掉到数字下面去——单独居中，才和右边那两组数平齐。 */
.ah-unit{order:-1;margin-right:auto;align-self:center;
  font-size:15px;letter-spacing:.06em;color:var(--ink-dim)}

.skill-grid{display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(168px,1fr))}
/* 一张卡就一行：左边技能名，右边当前值。困难/极难不在卡上显示，点开弹窗里有 */
/* 一行两个东西、字号又差一截，对基线会让技能名显得往下坠，改成竖直居中。
   上下 19px 是为了让框保持原来两行时的高度（约 73px），字号也按这个高度配 */
.rskill{background:var(--bg-panel);border:1px solid var(--line);border-radius:8px;padding:19px 11px;
  display:grid;grid-template-columns:1fr auto;align-items:center;column-gap:8px;
  font:inherit;color:inherit;text-align:left;cursor:pointer;
  transition:border-color .12s,transform .12s}
.rskill[hidden]{display:none}   /* .rskill 自己是 grid，压得过 hidden 的默认样式 */
.rskill:hover{border-color:var(--accent-soft);transform:translateY(-1px)}
.rskill:focus-visible{outline:2px solid var(--accent-soft);outline-offset:2px}
.rskill.occ{border-color:var(--accent);background:linear-gradient(180deg,#241d14,var(--bg-panel))}
.skill-head{grid-column:1;display:flex;align-items:baseline;justify-content:center;
  gap:5px;min-width:0}
/* 技能名在数字左边那块空地里居中，字号由 SKILL_FIT_JS 逐张量着放大（最大 30px），
   短名字撑满一半以上，长名字自己缩到刚好一行。行高压到 1.1，
   免得放大后的名字把框顶高——框高仍由右边 26px 的数字决定 */
.skill-name{font-size:17px;overflow-wrap:anywhere;line-height:1.1;min-width:0}
.skill-grid.fit .skill-name{white-space:nowrap;overflow-wrap:normal}
.star{color:var(--accent-soft);font-size:14px}
.star.hollow{color:var(--ink-faint)}
.skill-val,.rskill.tag::after{grid-column:2;grid-row:1;font-size:26px;font-weight:700;
  color:var(--accent-soft);font-variant-numeric:tabular-nums}

/* 状态 / 专长：和技能卡同一个网格、同一种框，只是右边没有数字。框高本来是右边那个
   26px 数字撑出来的，这里塞一个零宽空格的 ::after 顶着（跟着上面那条规则一起改字号），
   所以两栏的框和技能卡一样高、一样大 */
.rskill.tag::after{content:"\200b";width:0;overflow:hidden}
/* 带类目的状态卡：三列——类目 | 一条竖分割线 | 值。
   左边 auto，类目占多宽就多宽（顶多 56px，再长就截断，免得同一排卡的竖线错开）；
   右边 1fr 把剩下的横向空间全吃掉，所以左窄右宽。
   ⚠️ 三个格子都得写死 grid-row:1。撑框高的 ::after 自带显式的 grid-row，
   会先把格子占掉；只写 grid-column 不写 grid-row 的那个会被自动排布避开，
   直接掉到第二行去——类目在上、值在下，就错了。
   ::after 在这种卡上挪到第 3 列，和值挤在同一格（它宽 0，只管撑高度），
   所以带类目的卡和普通卡、技能卡还是一样高。
   值是这张卡的正主，字号跟技能卡上那个数字一样大（22px），在右边那格里居中。
   竖线右边约 90px：2~4 个汉字都是满字号，5 个起由 SKILL_FIT_JS 逐张缩一档，
   缩到 13px 还放不下才截断——完整内容鼠标移上去看气泡（标题是「类目 · 值」）。 */
.tag-cat{grid-template-columns:auto 1px minmax(0,1fr)}
.tag-k{grid-column:1;grid-row:1;font-size:13px;letter-spacing:.1em;color:var(--ink-dim);
  max-width:56px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tag-cut{grid-column:2;grid-row:1;align-self:stretch;background:var(--line)}
.tag-v{grid-column:3;grid-row:1;font-size:22px;line-height:1.1;color:var(--accent-soft);
  text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rskill.tag.tag-cat::after{grid-column:3}
.tag-v.empty{color:var(--ink-faint)}      /* 常驻类目还没填值：一道「—」占着位置 */
.tag-add{border-style:dashed}
.tag-add:hover{border-style:solid}
/* 加号外面套个灰圆：直径按自己的字号算（1.5em），比右边那个撑框高的 26px 行框矮，
   所以圆再大也顶不高框，加号框和技能卡还是一样高 */
.tag-plus{grid-column:1;justify-self:center;display:flex;align-items:center;
  justify-content:center;width:1.5em;height:1.5em;border-radius:50%;
  background:rgba(232,224,210,.10);font-size:26px;line-height:1;color:var(--ink-faint);
  transition:background .12s,color .12s}
.tag-add:hover .tag-plus{background:rgba(214,167,101,.18);color:var(--accent-soft)}
/* 只读版那个占位加号：框还在，但不亮、不描边、鼠标也不变手 */
.tag-add[disabled]{cursor:default;opacity:.55}
.tag-add[disabled]:hover{border-style:dashed}
.tag-add[disabled]:hover .tag-plus{background:rgba(232,224,210,.10);
  color:var(--ink-faint)}

/* 研习中：中间一个半圆（正在进行的工作），左右一边一个方块（各最多三条行动）。
   三样底边对齐——半圆的平边就落在两个方块的底边上 */
/* 整排铺满正文宽：两个正方形方块顶到最左最右，中间剩下的横向空间全归半圆，
   所以半圆被拉成一个扁椭圆（默认 580×240）。三样底边对齐——
   半圆的平边正好落在两个方块的底边上 */
.study-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:16px;
  align-items:end;margin:6px 0 40px}
/* ---- 修习中 / 研读中：圆形水位球 ----------------------------------------
   六个 --liq-* 变量写在 .vwrap 的 style 上（见 build.py 的 liq_vars()），
   不在这儿也不在 :root——两个球各挑各的配色。
   宽度和原来那个方块一样是 264，所以 .study-row 的版式一个字没改 */
.vwrap{width:264px}
.v-k{font-size:24px;letter-spacing:.14em;color:var(--ink-dim);margin-bottom:8px;
  height:1.4em;display:flex;align-items:center;justify-content:space-between;gap:8px}
.v-kn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vessel{position:relative;width:264px;height:264px}
.ball{position:absolute;inset:0;border-radius:50%;overflow:hidden;
  background:var(--bg-panel);border:1px solid var(--line);
  transition:border-color .14s}
.wv{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
/* 内壁的光压在水上面。box-shadow 画在自己的子元素底下，所以这一层必须
   单独摆在 svg 后面，否则水一涨上来就把它盖住了 */
.ball-glow{position:absolute;inset:0;border-radius:50%;pointer-events:none;
  box-shadow:inset 0 0 30px var(--liq-glow), inset 0 14px 36px rgba(0,0,0,.55);
  transition:box-shadow .2s}
/* 水位：整组上下挪，补间交给 transition。左右漂移和波幅起伏是 JS 每帧写 transform */
.lift{transition:transform .6s cubic-bezier(.4,0,.2,1)}
.ball .w-full{display:none}
.vessel.is-empty .wave,.vessel.is-empty .w-full{display:none}
.vessel.is-full .wave{display:none}
.vessel.is-full .w-full{display:block}
.vessel.is-full .ball{border-color:var(--liq-line)}
.ball-bg{fill:var(--bg-panel)}
/* 渐变的 fill="url(#…)" 写在元素属性上，**不能搬进这份外部样式表**：
   外部样式表里的 url(#id) 按规范相对样式表自身解析，Firefox 会找不着渐变
   （和上面 .arc-run 是同一个坑）。这儿只写 stop 的颜色 */
.gb0{stop-color:var(--liq-top);stop-opacity:.88}
.gb1{stop-color:var(--liq-mid);stop-opacity:.74}
.gb2{stop-color:var(--liq-deep);stop-opacity:.58}
.gk0{stop-color:var(--liq-top);stop-opacity:.36}
.gk1{stop-color:var(--liq-deep);stop-opacity:.22}
.gf0{stop-color:var(--liq-top);stop-opacity:.92}
.gf1{stop-color:var(--liq-deep);stop-opacity:.66}
/* 水面线是「带」不是描边：填充，粗细沿着波形变（SVG 的 stroke-width 一条路径只能是
   一个数，做不出变粗细，所以画成上沿贴波形、下沿让开 w(x) 的一条闭合带） */
.w-line{fill:var(--liq-line);opacity:.92}
.w-line2{fill:var(--liq-line2);opacity:.8}
/* 杂质两层，只出现在水体里，并且跟着水一起漂（.gscroll）。
   湍流是预先烤成位图的，滚动不重算滤镜——让带滤镜的元素跟着漂会每帧重算，直接卡死。
   注意这两个 mix-blend-mode 实际上「不生效」：带 clip-path 的 <g> 在 SVG 里
   构成隔离组，组内的混合够不着水体，真正渲染出来的是一层低透明度的灰盖在水上。
   看着是对的，别去「修」它——解开隔离会让 overlay/screen 真的生效，水色当场变样 */
.gscroll{will-change:transform}
.mottle{mix-blend-mode:overlay;opacity:var(--grit-blob,.34);pointer-events:none}
.grain{mix-blend-mode:screen;opacity:var(--grit-fine,.16);pointer-events:none}

/* 球里那一坨字。第 0 页是总览（所有名字 + 一个总百分比），翻页看单条 */
.v-in{position:absolute;inset:0;pointer-events:none}
.v-names{position:absolute;left:50%;top:41%;transform:translate(-50%,-50%);
  width:66%;display:flex;flex-direction:column;align-items:center;gap:2px}
.v-nmb,.v-one{background:none;border:none;padding:0;font:inherit;color:inherit;
  cursor:pointer;pointer-events:auto;border-radius:6px;
  transition:background .12s,color .12s}
.v-nmb{font-size:25px;line-height:1.5;color:var(--ink);overflow-wrap:anywhere;
  padding:0 6px;max-width:100%}
.v-nmb:hover{background:rgba(184,135,74,.18);color:var(--accent-soft)}
/* 总览那个大数：字号不动（再大就顶到球壁了），颜色和单条那个百分比取同一个金 */
.v-val{position:absolute;left:50%;top:79%;transform:translate(-50%,-50%);
  font-size:52px;line-height:1;color:var(--accent-soft);white-space:nowrap;
  font-variant-numeric:tabular-nums;letter-spacing:.01em}
.v-one{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:2px;text-align:center;padding:0 40px}
.v-one:hover .v-nm{color:var(--accent-soft)}
.v-nm{font-size:27px;color:var(--ink);line-height:1.25;overflow-wrap:anywhere;
  transition:color .12s}
.v-num{font-size:40px;color:var(--ink);font-variant-numeric:tabular-nums;
  line-height:1.2;margin-top:6px}
/* 百分比压在水里，用 --ink-faint 读不出来，取「研习中」那个金 */
.v-pct{font-size:18px;letter-spacing:.1em;color:var(--accent-soft);
  font-variant-numeric:tabular-nums}
.v-add{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:58px;height:58px;border-radius:50%;pointer-events:auto;cursor:pointer;
  background:rgba(232,224,210,.08);border:1px dashed var(--line);
  display:flex;align-items:center;justify-content:center;
  font:inherit;color:var(--ink-faint);transition:background .12s,color .12s}
.v-add:hover{background:rgba(214,167,101,.18);color:var(--accent-soft);
  border-style:solid}
.v-in .act-empty{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}
.v-nmb:focus-visible,.v-one:focus-visible,.v-add:focus-visible{
  outline:2px solid var(--accent-soft);outline-offset:2px}

/* 翻页箭头：压在球的左右下角，鼠标进球就一起亮 */
.v-arw{position:absolute;bottom:0;width:36px;height:36px;border-radius:50%;
  background:#171310;border:1px solid var(--line);padding:0;cursor:pointer;z-index:2;
  display:flex;align-items:center;justify-content:center;
  transition:border-color .14s,background .14s}
.v-arw::before{content:"";display:block;width:0;height:0;border-style:solid;
  transition:border-color .14s}
.v-next::before{border-width:8px 0 8px 11px;margin-left:3px;
  border-color:transparent transparent transparent var(--ink-dim)}
.v-prev::before{border-width:8px 11px 8px 0;margin-right:3px;
  border-color:transparent var(--ink-dim) transparent transparent}
.v-prev{left:0}
.v-next{right:0}
.v-arw:hover,.vwrap:hover .v-arw{border-color:var(--accent-soft);
  background:var(--bg-strong)}
.v-next:hover::before,.vwrap:hover .v-next::before{border-left-color:var(--accent-soft)}
.v-prev:hover::before,.vwrap:hover .v-prev::before{border-right-color:var(--accent-soft)}
.vwrap:hover .ball{border-color:var(--accent-soft)}
.v-arw:focus-visible{outline:2px solid var(--accent-soft);outline-offset:2px}
/* 一条行动都没有：没得翻，箭头和圆点一起收起来（位置照样占着，别让球跳） */
.vwrap.solo .v-arw,.vwrap.solo .v-dots i{visibility:hidden}
.v-dots{display:flex;gap:7px;justify-content:center;margin-top:12px;height:6px}
.v-dots i{width:6px;height:6px;border-radius:50%;background:var(--line);
  transition:background .18s}
.v-dots i.on{background:var(--accent-soft)}
.act-empty{color:var(--ink-faint);font-size:13px;font-style:italic}
/* 整个球就是入口：点空球直接开「添加」，点有条目的球摊开那一格的行动清单。
   球上不再挂小加号——一个 264px 的圆边上顶着颗 20px 的钮，怎么摆都难看 */
body:not(.ro) .ball{cursor:pointer}
/* 半圆正上方那个色盘钮：两个球共用这一个，点开在浮层里挑改哪一个。
   钮里一个球一颗小点，颜色是各自的前层线色，不点开也知道谁是谁 */
.arc-top{display:flex;justify-content:center;margin-bottom:10px}
/* 钮就是一条圆角色带，六格颜色，和浮层里那些配色块同一个长相 */
.pal-btn{display:block;padding:3px;border-radius:10px;cursor:pointer;font:inherit;
  background:rgba(232,224,210,.06);border:1px solid var(--line);
  transition:background .12s,border-color .12s}
.pal-btn:hover{background:rgba(214,167,101,.16);border-color:var(--accent-soft)}
.pal-btn[aria-expanded="true"]{background:rgba(214,167,101,.22);
  border-color:var(--accent-soft)}
.pal-btn:focus-visible{outline:2px solid var(--accent-soft);outline-offset:2px}
.pal-strip{display:flex;width:62px;height:22px;border-radius:6px;overflow:hidden}
.pal-strip i{flex:1}

/* 调色板浮层。整页就一个，点哪个球就挂到哪个球边上（JS 摆位置）。
   只有编辑版才生成——线上只读版没有能存改动的地方，给个改不动的面板是骗人 */
/* 一排摆得下六套配色，摆不下就退回三排两列（窄屏），再窄就两列 */
.look-pop{position:absolute;z-index:60;width:min(980px,calc(100vw - 24px));
  padding:18px;background:var(--bg-panel);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:0 18px 44px rgba(0,0,0,.55)}
.look-hd{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-size:12px;letter-spacing:.14em;color:var(--ink-dim);margin-bottom:10px}
.look-x{background:none;border:none;padding:0;width:1.5em;height:1.5em;
  color:var(--ink-faint);font:inherit;font-size:17px;line-height:1;cursor:pointer;
  border-radius:50%;transition:background .12s,color .12s}
.look-x:hover{background:rgba(232,224,210,.10);color:var(--ink)}
/* 顶上那一排：改哪个球。两个球共用一个面板，先挑球再挑色。
   钮的底色就是那个球的前层线色（JS 写 style），所以字得是深色才读得出来——
   那十二个前层线色都是中明度往上的，压深字一律看得清 */
.look-tabs{display:flex;gap:9px;margin-bottom:14px}
.look-tab{flex:1;padding:9px 0;border-radius:8px;cursor:pointer;font:inherit;
  font-size:14px;letter-spacing:.08em;color:var(--ink);
  border:1px solid var(--line);transition:border-color .12s,box-shadow .12s}
.look-tab:hover{border-color:var(--accent-soft)}
/* 挑中的那个铺满色，字压深才读得出来——十二套的前层线色都是中明度往上的 */
.look-tab.on{color:#1b1815;border-color:var(--accent-soft);
  box-shadow:0 0 0 1px var(--accent-soft)}
.look-tab:focus-visible{outline:2px solid var(--accent-soft);outline-offset:2px}
/* 满宽（980）时正好一排六个，每块约 149px——比原来那个三列的窄面板宽一半多。
   auto-fit 是为了窄屏：面板被 100vw 夹住时自己退到四列、三列，不用另写断点 */
.look-pal{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));
  gap:10px}
.look-sw{padding:0;border-radius:8px;cursor:pointer;background:none;overflow:hidden;
  border:1px solid var(--line);font:inherit;transition:border-color .12s}
.look-sw:hover{border-color:var(--accent-soft)}
.look-sw.on{border-color:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--accent-soft)}
.look-sw u{display:flex;height:34px;text-decoration:none}
.look-sw u b{flex:1}
.look-sw em{display:block;font-style:normal;font-size:12px;color:var(--ink-dim);
  padding:5px 0 6px;text-align:center;letter-spacing:.06em}
.look-sw.on em{color:var(--ink)}
.look-sw:focus-visible,.look-more:focus-visible{outline:2px solid var(--accent-soft);
  outline-offset:2px}
/* 「调参」是二级：默认收起来，点开才露出那一排滑块 */
.look-more{display:block;width:100%;margin-top:12px;padding:6px 0;
  background:rgba(232,224,210,.06);border:1px solid var(--line);border-radius:6px;
  color:var(--ink-dim);font:inherit;font-size:13px;cursor:pointer;
  transition:background .12s,color .12s}
.look-more:hover{background:rgba(214,167,101,.14);color:var(--accent-soft)}
.look-knobs{margin-top:10px;display:flex;flex-direction:column;gap:7px}
/* [hidden] 是 UA 表里的 display:none，class 上写了 display:flex 就压过它了——
   少了这一条，「调参」那排滑块一进来就摊着，二级按钮点了也收不回去 */
.look-knobs[hidden]{display:none}
.lab{display:flex;align-items:center;gap:10px;color:var(--ink-dim);font-size:13px}
.lab>span{min-width:4.6em;flex:none}
.lab s{text-decoration:none;color:var(--ink);font-variant-numeric:tabular-nums;
  min-width:3.6em;text-align:right;flex:none}
.lab-track{position:relative;flex:1;min-width:0;display:flex;align-items:center}
.lab-track input{width:100%;margin:0;display:block;accent-color:var(--accent-soft)}
/* 出厂值那道灰印子：钉在原本的位置上不动，拖走了也知道原来在哪。
   8px / 16px 是滑块那个圆钮的半径和直径——印子要和钮心对齐，
   所以可用行程是「整条减一个钮宽」，起点再往右让半个钮 */
.lab-ghost{position:absolute;top:50%;margin-top:-7px;margin-left:-1px;
  width:2px;height:14px;border-radius:1px;background:var(--ink-faint);
  opacity:.75;pointer-events:none;
  left:calc(8px + (100% - 16px) * var(--f))}
.look-ft{display:flex;align-items:center;justify-content:flex-end;gap:10px;
  margin-top:12px;font-size:12px;color:var(--ink-faint)}

/* 半圆：横向压扁的半个椭圆，平边朝下。border-radius 的斜杠写法给的正是
   「横半径 = 宽的一半、竖半径 = 整个高」，所以上沿是一整条椭圆弧。
   四条边都有，底下那条实线把椭圆封上，正好压在两个方块的底线上。
   max-width/height 要和 build.py 顶上的 ARC_W / ARC_H 一样——上面那条进度弧是按
   那两个数画的 SVG，对不上就和边框错开了。宽度可以随窗口缩：border-radius 是百分比、
   SVG 又是 preserveAspectRatio:none，两样都跟着一起横向拉伸，缩了照样重合 */
/* 中间这一列：色盘钮在上，半圆在下。半圆是最后一个，
   所以 .study-row 那个 align-items:end 照样把半圆的平边对到两个球的底边上 */
.arc-col{display:flex;flex-direction:column;align-items:center;
  width:100%;min-width:0}
.act-arc{position:relative;width:100%;max-width:580px;height:240px;
  background:var(--bg-panel);border:1px solid var(--line);
  border-radius:50% 50% 0 0 / 100% 100% 0 0;
  cursor:pointer;transition:border-color .12s}
.act-arc:hover{border-color:var(--accent-soft)}
/* 顶上那条当月进度，做成一道嵌在暗槽里的水。preserveAspectRatio:none 让弧跟着框
   一起横向拉伸，线宽也跟着一起缩——**千万别加 vector-effect:non-scaling-stroke**：
   加了以后 Chrome 会把虚线放到设备像素里去算，而 pathLength 的归一化系数是按
   用户坐标的弧长算的，两边差一个屏幕缩放倍数（2 倍屏上 67.74% 会画成 34%，
   空隙也不够长，弧尾巴上还会再冒出一截——就是「两边都有水」那个毛病）。
   线宽跟着缩还有个好处：水带外沿离边框永远是那 1px 的比例，缩到多小都不会骑出去。
   底槽 29px、水身 22px，水带内外各留 3px 暗边——**两边必须一样宽**：
   外面那道线是 .act-arc 的 border（贴在槽外沿），里面那道是 .arc-edge
   （骑在槽内沿），两条线到水的距离都是 3px 才对称。这几个数是 build.py 顶上
   ARC_GAP / ARC_RUN 一路倒推出来的，改哪个都得三处一起改。
   端帽必须是 butt（切平）：圆头会在半圆那条平底线底下鼓出两个半圆，
   水头也会顶成个椭圆——切平了才是齐口。
   水身和浪花的颜色是两块会自己往右挪的重复渐变（见 build.py 的 arc_wave()），
   笔刷在动，线本身不动。纯装饰，点击穿过去打开填写弹窗 */
.arc-bar{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;overflow:visible}
.arc-track,.arc-run{fill:none;stroke-linecap:butt}
.arc-track{stroke:var(--bg-strong);stroke-width:29}
/* 水身和浪花的笔刷（url(#arc-wv) / url(#arc-fm)）写在元素属性上，不在这儿——
   外部样式表里的 url(#id) 是相对样式表解析的，搬进来 Firefox 就画不出水 */
.arc-run{stroke-width:22}
/* 遮罩里那道黑橡皮：从进度点往后盖住水带，自己被 feGaussianBlur 糊开，
   糊出来的这条 alpha 斜坡就是水尖的渐变（叠半透明层会露出一条条硬边，别再那么干）。
   比水带宽得多，两侧的槽壁才落在斜坡外面、不跟着糊 */
.arc-cut{fill:none;stroke:#000;stroke-width:60}
/* 水槽内壁那道细线，和外面那圈边框（.act-arc 的 border）对称——粗细、颜色、
   连 hover 跟着变金色都一样。这条线没有 dasharray，所以给它加
   non-scaling-stroke 是安全的（坑在虚线上，见上面），1px 就永远是 1px，
   和外面那道 CSS 边框才对得齐 */
.arc-edge{fill:none;stroke:var(--line);stroke-width:1;
  vector-effect:non-scaling-stroke;transition:stroke .12s}
.act-arc:hover .arc-edge{stroke:var(--accent-soft)}
/* 渐变里那几个 stop 的颜色。挂在 class 上写进 CSS，浅色/打印版才好一起换 */
.wv-a{stop-color:var(--water)}
.wv-b{stop-color:var(--water-lit)}
.fm-a{stop-color:var(--water-lit);stop-opacity:0}
.fm-b{stop-color:#fff;stop-opacity:.36}
/* 半圆里那三样各摆各的位，横向一律居中（left:50% + translateX(-50%)）。
   竖着的位置写成百分比，改了 ARC_H 也不用跟着调 */
.arc-in{position:absolute;inset:0;text-align:center}
.arc-day,.arc-v,.arc-date{position:absolute;left:50%;transform:translate(-50%,-50%)}
/* 当月还剩几天。原来是圆弧顶上一颗带框的小胶囊，现在挪到盘子下半截、
   去掉框、放到和两个球那个总览大数一样大（52px / 同一个金）——
   一排三样各自都有一个大数字落在下面偏低的位置，看着才是一套的。
   80% 是照着球里 .v-val 的 79% 配的；顶上留白也不亏，进度弧本来就在那圈边上 */
.arc-day{top:80%;font-size:52px;line-height:1;letter-spacing:.01em;
  color:var(--accent-soft);font-variant-numeric:tabular-nums;
  white-space:nowrap;pointer-events:none}
/* 填进去的工作：圆里正中偏下一点。从 61% 提到 54%，给底下那个大数腾地方 */
.arc-v{top:54%;width:76%;font-size:26px;line-height:1.2;color:var(--ink);
  overflow-wrap:anywhere}
.arc-empty{color:var(--ink-faint);font-size:15px;font-style:italic}
/* 几年几月落在圆外面、平边底下。绝对定位不占位置，
   .study-row 底下那 40px 外边距就是留给它的 */
.arc-date{top:100%;transform:translate(-50%,0);margin-top:10px;white-space:nowrap;
  font-size:18px;letter-spacing:.1em;color:var(--accent-soft);
  font-variant-numeric:tabular-nums}

/* 页面上能点开改的地方：状态/专长的卡、三张表的行、背景故事那八块和正文 */
.edit-tb tbody tr[data-i]{cursor:pointer}
.edit-tb tbody tr[data-i]:hover td{background:rgba(184,135,74,.10)}
.tb-empty td{color:var(--ink-faint);font-style:italic;text-align:center}
.edit-blk{cursor:pointer;border-radius:8px;transition:background .12s}
.edit-blk:hover{background:rgba(184,135,74,.07)}
/* 线上只读版：填写入口都没生成，点得动的那副样子也一并收掉 */
body.ro .edit-tb tbody tr[data-i]{cursor:default}
body.ro .edit-tb tbody tr[data-i]:hover td{background:none}
body.ro .edit-blk{cursor:default}
body.ro .edit-blk:hover{background:none}
body.ro .rskill.tag{cursor:default}
body.ro .act-it,body.ro .act-arc{cursor:default}
/* 编辑版的成长表：能改的格子点一下就变输入框 */
.sheet td[data-col]{cursor:text}
.sheet td[data-col]:hover{background:rgba(184,135,74,.13);
  box-shadow:inset 0 0 0 1px var(--accent)}
.sheet td[data-calc]{color:var(--accent-soft)}
.gr-in{font:inherit;font-size:14px;line-height:1.5;width:100%;min-width:56px;
  color:var(--ink);background:var(--bg-strong);border:1px solid var(--accent);
  border-radius:4px;padding:3px 6px;display:block}
textarea.gr-in{min-height:92px;resize:vertical}
/* 表长，这条跟着屏幕底走，改到哪儿都够得着 */
.gr-bar{position:sticky;bottom:12px;margin-top:20px;z-index:8;
  box-shadow:0 6px 20px rgba(0,0,0,.45)}
/* 「改了几格」占住中间，撤掉改动推到最右边 */
.gr-bar #gr-count{margin-right:auto}
/* 「＋ 加一个月」是这一排的最后一个，顶在最右边。它和四个筛选钮之间隔着
   #mo-note（多数时候是空的），一左一右两个 gap 就是那 18px 间距，
   看得出它不是第五档筛选，不用再另加外边距。 */
/* 页面最下面那条：本机改了几栏、导出、丢掉 */
.edit-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:36px;
  padding:12px 16px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--bg-panel)}
.edit-bar-k{font-size:13px;letter-spacing:.14em;color:var(--ink-dim)}
.edit-bar #edit-export{margin-left:auto}
/* 弹窗里的表单：一栏一个格子，长文本给 textarea */
.edit-title{margin:0 0 16px}
.edit-f{display:block;margin-bottom:13px}
/* 行动那个弹窗：名字一格，「已完成 / 总数」两个小格并排跟在右边。
   两个数是一对，摞成上下两行看着像两件不相干的事 */
.edit-row{display:flex;gap:10px;align-items:flex-start}
.edit-row .edit-f{flex:0 0 96px;margin-bottom:13px}
.edit-row .edit-f:first-child{flex:1 1 auto;min-width:0}
.edit-row input[type=number]{text-align:center;padding-left:6px;padding-right:6px}
/* 两个数中间那道斜杠。字号/行高/上下 padding/边框宽度都照着 .edit-f input 抄，
   加上那个空的 .edit-lab 占位，斜杠就自己落在两个框的正中间——不用量像素 */
.edit-row .edit-sep{flex:0 0 auto}
.edit-sep b{display:block;font:inherit;font-weight:400;font-size:17px;line-height:1.7;
  padding:10px 0;border:1px solid transparent;color:var(--ink-dim);
  text-align:center;width:1.1em}
.edit-f[hidden]{display:none}   /* 上面那条 display 压得过 [hidden] 的默认样式 */
.desc-add{margin-bottom:13px}
/* 图片那一格：没图时就一个「＋ 选一张图片」，排在描述后面；
   有图了整格挪到名字和描述中间（JS 的 placePic() 挪），预览压在一个定高的框里 */
/* 挑文件那个 input 是拿钮去 click() 的，不该露脸。光写 hidden 压不住——
   上面 .edit-f input 那条 display:block 比 UA 表里 [hidden] 的 display:none 强
   （和 .look-knobs[hidden] 是同一个坑）。type=hidden 那个不用管，UA 表里带 !important */
.edit-pic input[type=file]{display:none}
.pic-box{display:flex;flex-direction:column;align-items:flex-start;gap:9px}
.pic-img{display:block;max-width:100%;max-height:260px;border-radius:8px;
  border:1px solid var(--line);background:var(--bg-soft)}
.pic-btns{display:flex;gap:9px}
/* 「还能粘贴」那句话。.pic-box 是竖着排的，所以它自己落在钮底下 */
.pic-tip{font-size:13px;letter-spacing:.04em;color:var(--ink-faint)}
.edit-lab{display:block;font-size:13px;letter-spacing:.14em;color:var(--ink-dim);
  margin-bottom:5px}
.edit-f input,.edit-f textarea{font:inherit;font-size:17px;line-height:1.7;color:var(--ink);
  background:var(--bg-soft);border:1px solid var(--line);border-radius:8px;
  padding:10px 13px;width:100%;display:block;resize:vertical}
.edit-f input:focus,.edit-f textarea:focus{outline:none;border-color:var(--accent)}
/* 带下拉的那几个输入框（值 / 类目）：箭头默认是内联排的，跟着文字基线走，看着偏下。
   右边留出 padding，免得字写长了钻到箭头底下。
 ⚠️ 这个箭头是画不进它自己的盒子的。top:50%+translateY(-50%) 摆正的只是「元素盒」，
   浏览器把那个三角画在盒子底下，实测比正中低 6px（成长表）/ 8px（这里）。
   试过 background-position:center、background-origin、background-size:contain——
   这几个对它一律无效，唯一推得动的就是 transform。所以在 -50% 之外再补一段实测的
   位移。数值是截图逐像素量出来的（把箭头 opacity:0 渲一遍，两张图相减找三角），
   改了字号或 --arrow 就得重量一次。
   width/height/font-size/background-size 四个还是要一起给，少一个大小就不听话。 */
.edit-f input[list]{--arrow:18px;position:relative;padding-right:38px}
.edit-f input[list]::-webkit-calendar-picker-indicator{position:absolute;right:13px;
  top:50%;font-size:var(--arrow);width:var(--arrow);height:var(--arrow);
  background-size:var(--arrow) var(--arrow);
  transform:translateY(-50%) translateY(-8px);
  margin:0;padding:0;opacity:.7;cursor:pointer}
/* 新加状态卡时顶上那一排：普通 / 带类目。默认「普通」，也就是原来的加法 */
.edit-mode{display:flex;gap:20px;margin-bottom:15px;font-size:15px;color:var(--ink-dim)}
.edit-mode label{display:flex;align-items:center;gap:6px;cursor:pointer}
/* 类目那一格和底下的「管理类目」是一块，选「普通」时整块收起来 */
.cat-box[hidden]{display:none}
.cat-box .edit-f{margin-bottom:7px}
.cat-mng,.cat-one{margin-bottom:13px}
/* 点球开的那个面板：一个球里那几条行动摊成一列。
   一行一条——名字、已完成/总数、百分比，底下压一条进度线。点一行进去改或删 */
.act-list{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.act-row{position:relative;display:flex;align-items:baseline;gap:10px;width:100%;
  padding:11px 13px 13px;border-radius:10px;cursor:pointer;text-align:left;
  font:inherit;background:var(--bg-soft);border:1px solid var(--line);
  overflow:hidden;transition:background .12s,border-color .12s}
.act-row:hover{border-color:var(--accent-soft);background:rgba(184,135,74,.10)}
.act-row:focus-visible{outline:2px solid var(--accent-soft);outline-offset:2px}
.act-rn{flex:1;min-width:0;font-size:17px;color:var(--ink);overflow-wrap:anywhere}
.act-rv{flex:none;font-size:15px;color:var(--ink-dim);
  font-variant-numeric:tabular-nums}
.act-rp{flex:none;min-width:3.2em;text-align:right;font-size:13px;
  letter-spacing:.06em;color:var(--accent-soft);font-variant-numeric:tabular-nums}
/* 进度线贴着行的底边，宽度就是这一条的完成比 */
.act-rbar{position:absolute;left:0;bottom:0;height:2px;width:100%;
  transform:scaleX(var(--f));transform-origin:left;
  background:var(--accent-soft);opacity:.75}
.act-new{margin-bottom:13px}
/* 类目管理：一行一个类目——名字、一串下拉备选值、挪位置、删。
   行的先后就是卡在状态栏里的先后，所以要能上下挪 */
.cat-list{max-height:52vh;overflow:auto;margin-bottom:10px}
.cat-row{display:flex;align-items:center;gap:6px;margin-bottom:6px}
.cat-row input{font:inherit;font-size:15px;color:var(--ink);background:var(--bg-soft);
  border:1px solid var(--line);border-radius:8px;padding:7px 10px;min-width:0}
.cat-row input:focus{outline:none;border-color:var(--accent)}
.cat-k{flex:0 0 92px}
.cat-o{flex:1}
.cat-b{flex:0 0 auto;font:inherit;font-size:15px;line-height:1;color:var(--ink-dim);
  background:var(--bg-soft);border:1px solid var(--line);border-radius:8px;
  padding:8px 10px;cursor:pointer;transition:color .12s,border-color .12s}
.cat-b:hover{color:var(--accent-soft);border-color:var(--accent-soft)}
/* 删类目不毁数据（值会变成普通的带类目卡），但毕竟会少一张常驻卡，给点区分 */
.cat-x:hover{color:#c4705a;border-color:#c4705a}
/* 挑技能的弹窗：一行一个技能，勾上的才在页面上显示 */
/* 挑技能面板顶上的分类筛选 */
.pick-cats{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 0}
.mo-btn.pc{padding:4px 11px;font-size:12.5px;letter-spacing:.04em}
.mo-btn.pc.on{border-color:var(--accent);color:var(--accent-soft);
  background:rgba(184,135,74,.14)}
.pick-bar{display:flex;align-items:center;gap:10px;margin:10px 0}
.pick-n{margin-right:auto;font-size:14px;color:var(--ink-dim)}
/* 38vh 是让出分类那一排的高度，弹窗整体维持加分类按钮之前的样子 */
.pick-list{max-height:38vh;overflow:auto;border:1px solid var(--line);border-radius:8px}
.pick-it{display:flex;align-items:center;gap:10px;padding:8px 13px;cursor:pointer;
  border-bottom:1px solid var(--line)}
.pick-it:last-child{border-bottom:0}
.pick-it:hover{background:rgba(184,135,74,.10)}
.pick-it[hidden]{display:none}
.pick-it input{width:16px;height:16px;accent-color:var(--accent);flex:none}
.pick-nm{color:var(--ink);font-size:16px}
.pick-nm .star{margin-left:5px}
.pick-coc{margin-right:auto;color:var(--ink-faint);font-size:13px}
.pick-v{color:var(--accent-soft);font-variant-numeric:tabular-nums}
.edit-check{display:flex;align-items:center;gap:8px;font-size:15px;color:var(--ink-dim);
  cursor:pointer}
.edit-btns{display:flex;align-items:center;gap:10px;margin-top:16px}
.edit-btns #edit-save{margin-left:auto;border-color:var(--accent);color:var(--ink)}
.edit-btns #edit-del:hover{border-color:#a5514a;color:#e2a09a}

/* 悬停提示：内容藏在卡片里，由 JS 复制到这个固定定位的气泡上 */
.sk-tip{position:fixed;z-index:40;max-width:min(520px,92vw);background:#2a241d;
  border:1px solid var(--accent);border-radius:8px;padding:14px 17px;
  box-shadow:0 8px 26px rgba(0,0,0,.6);pointer-events:none;font-size:17px;line-height:1.6;
  /* 介绍太长时不许顶出视口：自己封顶，超出部分裁掉（完整的点开弹窗看） */
  max-height:calc(100vh - 16px);overflow:hidden}
.sk-tip .tip-title{color:var(--accent-soft);font-weight:600;margin-bottom:6px;letter-spacing:.04em}
.sk-tip .tip-band{margin-left:8px;font-size:14px;color:var(--bg);background:var(--accent);
  border-radius:3px;padding:1px 7px;font-weight:400;letter-spacing:.06em}
.sk-tip .tip-text{color:var(--ink)}
.sk-tip .tip-desc{margin-top:10px;padding-top:10px;border-top:1px solid var(--line);
  color:var(--ink-dim);font-size:16px;line-height:1.65}
.sk-tip .tip-desc-t{display:block;color:var(--accent-soft);font-weight:600;
  letter-spacing:.04em;margin-bottom:4px}
.sk-tip .tip-more{margin-top:9px;color:var(--ink-faint);font-size:15px}
/* 雷达图顶点的气泡：跟着鼠标定位，样式和属性格子那个气泡一致 */
.f-tip{position:fixed;z-index:40;background:#2a241d;border:1px solid var(--accent);
  color:var(--ink);padding:10px 15px;border-radius:8px;font-size:18px;line-height:1.4;
  letter-spacing:.02em;white-space:nowrap;box-shadow:0 6px 18px rgba(0,0,0,.55);
  pointer-events:none}

/* 技能弹窗 */
.modal{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;
  padding:20px}
.modal[hidden]{display:none}
.modal-back{position:absolute;inset:0;background:rgba(0,0,0,.66)}
/* 弹窗整体比正文放大 125% */
.modal-card{position:relative;background:var(--bg-panel);border:1px solid var(--accent);
  border-radius:14px;max-width:825px;width:100%;max-height:88vh;overflow-y:auto;
  padding:28px 30px;box-shadow:0 20px 60px rgba(0,0,0,.6)}
.modal-x{position:absolute;top:12px;right:15px;background:none;border:none;color:var(--ink-dim);
  font-size:30px;line-height:1;cursor:pointer;padding:5px 10px;border-radius:6px}
.modal-x:hover{color:var(--ink);background:var(--bg-soft)}
.d-name{margin:0;font-size:30px;letter-spacing:.05em}
.d-stats{display:grid;gap:10px;grid-template-columns:repeat(3,1fr);margin:18px 0}
.d-stat{background:var(--bg-soft);border:1px solid var(--line);border-radius:10px;
  padding:12px 8px;text-align:center}
.d-stat-k{display:block;font-size:14px;color:var(--ink-faint);letter-spacing:.1em}
.d-stat-v{display:block;font-size:30px;font-weight:700;color:var(--accent-soft);
  font-variant-numeric:tabular-nums}
.d-desc{margin:0 0 18px;font-size:16px;line-height:1.7;background:var(--bg-soft);
  border-left:4px solid var(--accent);border-radius:0 10px 10px 0;padding:14px 18px;
  color:var(--ink-dim)}
.d-desc-t{color:var(--ink-dim);font-size:15px;letter-spacing:.12em;margin-bottom:8px}
.d-desc-en{color:var(--accent-soft);font-weight:600;letter-spacing:.04em}
.d-ladder{min-width:0;font-size:16px}
.d-ladder th,.d-ladder td{padding:9px 13px;border-bottom:1px solid var(--line);text-align:left;
  vertical-align:top}
.d-ladder th{background:var(--bg-soft);color:var(--ink-dim);font-size:15px;letter-spacing:.1em}
.d-ladder .d-band{white-space:nowrap;color:var(--ink-dim);font-variant-numeric:tabular-nums}
.d-ladder tr.on td{background:rgba(184,135,74,.16);color:var(--ink)}
.d-ladder tr.on .d-band{color:var(--accent-soft);font-weight:700}
.d-source{margin:15px 0 0;font-size:15px;color:var(--ink-faint);line-height:1.6}

/* 技能分组：不套框——技能卡自己已经有边框和底色了，外面再套一层
   就成了框里套框，还把「这组只有一张卡」的空白圈起来强调。这里只留
   一行轻标题，卡片照旧直接铺在页面底色上。 */
.skill-groups{display:flex;flex-direction:column;gap:0}
.skg{border:none;background:none;border-radius:0}
/* 线画在类名下面（不是上面），组名和它自己的卡片之间隔一条 */
.skg-h{list-style:none;cursor:pointer;padding:16px 2px 8px;display:flex;
  align-items:baseline;gap:10px;user-select:none;
  border-bottom:1px solid var(--line)}
.skg-h::-webkit-details-marker{display:none}
.skg-h::before{content:"▸";color:var(--ink-faint);font-size:12px;
  transition:transform .15s;display:inline-block;line-height:1}
.skg[open] > .skg-h::before{transform:rotate(90deg)}
.skg-h:hover .skg-t{color:var(--accent-soft)}
.skg-h:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* 比 h2（17px 金色）小一号、颜色浅一档，但一眼要认得出是个分类 */
.skg-t{color:var(--ink);letter-spacing:.2em;font-size:24px;font-weight:600}
.skg-n{color:var(--ink-faint);font-size:12px;font-variant-numeric:tabular-nums;
  margin-left:auto}
.skg .skill-grid{padding:12px 0 4px}
/* 没归类的那些：不写类名，但底下那条线照画，跟别的组对齐 */
.skg-loose{padding:2px 0 12px;border-bottom:1px solid var(--line)}
/* 「＋」跟着最后一组的卡片一起排（drawAdd 会把它塞进那一组的 grid），
   所以它就是一张普通技能卡的大小。万一没有任何分组露出来，它落在
   .skill-groups 底下，这时自己拿回间距、也别拉成横贯一行的长条 */
.skill-groups > .skill-add{margin-top:16px;align-self:start;
  min-width:156px;max-width:210px}

/* 拿得出手的技能：只有练到 50 以上才出现，没有就整块不渲染 */
/* 没有标题也没有分割线：够格的技能直接列出来，不够格整块不渲染。
   字号跟技能卡里的名字（20px）一致，条和数值跟着放大。 */
.sbars{margin:0 0 6px;padding:0}
.sbar{display:flex;align-items:center;gap:16px;padding:8px 2px;font-size:21px}
.sbar-n{flex:none;width:6.4em;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;color:var(--ink)}
.sbar-t{flex:1;min-width:60px;height:8px;background:var(--bg-strong);
  border-radius:4px;overflow:hidden}
.sbar-f{display:block;height:100%;background:var(--accent);border-radius:4px}
/* 只有当前值抢眼；「/100」是刻度不是数据，压成暗色小字 */
.sbar-v{flex:none;width:4.4em;text-align:right;font-weight:700;
  color:var(--accent-soft);font-variant-numeric:tabular-nums}
.sbar-v i,.sbar-v u{font-style:normal;text-decoration:none;
  color:var(--ink-faint);font-weight:400;font-size:.7em}
.sbar-v i{padding:0 1px}
@media (max-width:640px){
  .sbar{gap:11px;font-size:18px;padding:7px 2px}
  .sbar-n{width:5.6em}
}

/* 表格 */
.table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--radius)}
table{border-collapse:collapse;width:100%;font-size:13px}
table.grid{min-width:520px}
.grid th,.grid td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--line);
  vertical-align:top}
.grid th{background:var(--bg-soft);color:var(--ink-dim);font-weight:600;letter-spacing:.1em;
  font-size:12px;white-space:nowrap}
.grid tbody tr:last-child td{border-bottom:none}
.grid tbody tr:nth-child(even){background:rgba(255,255,255,.015)}

/* 参考表：保留 xlsx 的合并结构 */
/* 参考表：宽度交给内容决定，横向滚动交给页面本身（滚动条固定在窗口底部） */
.sheet-wrap{overflow:visible;width:max-content;max-width:none}
/* 四个参考页的框和第一页技能卡片(.rskill)统一：panel 底色 + 1px 边 + 8px 圆角。
   width 是 max-content，overflow:hidden 只裁圆角不裁内容，宽表照样撑开页面。
   表格自己的最外圈边去掉，不然和外框叠成 2px 粗边，角上也圆不起来 */
.sheet-wrap{background:var(--bg-panel);border-radius:8px;overflow:hidden}
.sheet tr:first-child td{border-top:none}
.sheet tr:last-child td{border-bottom:none}
.sheet td:first-child{border-left:none}
.sheet td:last-child{border-right:none}
.sheet-wrap .sheet{width:auto;min-width:0}
table.sheet{width:auto;min-width:100%;font-size:13px;table-layout:auto}
.sheet td{border:1px solid var(--line);padding:6px 9px;vertical-align:top;
  min-width:52px;max-width:300px;overflow-wrap:break-word}
.sheet td.nw{white-space:nowrap}
.sheet td.wide{min-width:172px}
.sheet td.b{color:var(--accent-soft);font-weight:600}
.sheet td.fill{background:var(--bg-soft)}
.sheet td.center{text-align:center}
/* 技能查询那张表撑满正文宽度（和标题下那条横线一样长） */
.sheet-wrap.full-wrap{width:auto}
.sheet-wrap.full-wrap .sheet.full{width:100%}
.sheet td.box{max-width:none;white-space:pre-wrap;line-height:1.85;font-size:15px;
  padding:12px 16px;color:var(--ink-dim)}
/* 技能解释：一档一行铺满整格。height:1px 是老把戏——格子的真实高度由右边
   成功率阶梯那些行撑出来，写死 1px 之后里面的 .lad 才能按 100% 拉到满格 */
.sheet td.boxfill{padding:0;height:1px}
.lad{display:flex;flex-direction:column;height:100%;white-space:normal}
/* 档位和说明中间那道竖线：内边距挪到两个 span 上、行内改成 stretch，
   竖线才能顶满整行高度，和上下的横线接在一起 */
.lad-row{flex:1;display:flex;align-items:stretch;border-bottom:1px solid var(--line)}
.lad-row:last-child{border-bottom:none}
.lad-b{flex:0 0 84px;display:flex;align-items:center;justify-content:flex-end;
  padding:7px 14px 7px 17px;border-right:1px solid var(--line);
  color:var(--ink-faint);letter-spacing:.04em;font-variant-numeric:tabular-nums}
.lad-t{flex:1;min-width:0;display:flex;align-items:center;padding:7px 17px 7px 15px}
/* 当前值落在哪一档，那一行高亮 */
.lad-row.on{background:rgba(184,135,74,.14);color:var(--ink);font-weight:600}
.lad-row.on .lad-b{color:var(--accent-soft)}
/* 还没选技能时的提示文字：格子的内边距被 boxfill 收走了，这里自己补上 */
.lad-ph{padding:12px 17px;white-space:normal}
/* 「技能解释」的管理模式（只有编辑版有）：点开之后每一档都能点开改 */
.sd-btn{margin-left:12px;vertical-align:middle}
body.sd-on .lad-row[data-band]{cursor:text}
body.sd-on .lad-row[data-band]:hover{background:rgba(184,135,74,.10)}
body.sd-on .lad-row[data-band]:hover .lad-t{box-shadow:inset 0 0 0 1px var(--accent)}
.lad-row.sd-dirty .lad-t{color:var(--accent-soft)}
.lad-t .sd-in{font:inherit;font-size:15px;line-height:1.6;width:100%;
  color:var(--ink);background:var(--bg-strong);border:1px solid var(--accent);
  border-radius:4px;padding:4px 7px;display:block;resize:vertical}
/* 表长，这条也跟着屏幕底走 */
.sd-bar{position:sticky;bottom:12px;margin-top:20px;z-index:8;
  box-shadow:0 6px 20px rgba(0,0,0,.45)}
.sd-bar #sd-note{margin-right:auto}
/* 搜索框填满整个「技能名称」格 */
.sheet td.qcell{padding:0;height:1px;position:relative}
/* 没选技能时的提示语。铺满整格再用 flex 居中——横竖都对得准，
   比正文大一圈、比选中后的技能名小一圈，一眼看得出它是提示不是内容 */
.qph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  pointer-events:none;font-size:clamp(22px,3.2vw,38px);letter-spacing:.06em;
  color:var(--ink-faint)}
.qph[hidden]{display:none}
/* 查询结果那两格：格子高 122px，原来字才 23px，空得慌（旁边输入框是 66px）。
   两格内容长度差很多，所以分开给——
   「当前值」最多两位数字，可以放到接近输入框的量级；
   「归类」最长 14 个字（「交涉技能 / 非常规 专业化」），要留出换三行的余地，封顶低些。
   都用 vw 跟着表格宽度走，窄屏时一起缩，比例不变。 */
.sheet td.qval{font-size:clamp(23px,2vw,30px);line-height:1.25;text-align:center;
  vertical-align:middle;white-space:pre-wrap}
#sk-rate{font-size:clamp(28px,3.6vw,54px);line-height:1.1}
/* 标题行的高度由右边阶梯那一行撑出来，比标题本身高；
   td 默认 vertical-align:top，不写 middle 的话上紧下松 */
.sheet td.qtitle{font-size:19px;text-align:center;letter-spacing:.08em;
  vertical-align:middle}
/* 技能介绍这一格只放大字号，排版保持原样（顶端对齐） */
#sk-intro{font-size:clamp(19px,1.7vw,28px)}
#sk-q{--arrow:clamp(16px,2.2vw,32px);   /* 下拉箭头多大，见下面那条 */
  position:relative;display:block;width:100%;height:100%;min-height:64px;
  box-sizing:border-box;font:inherit;font-size:clamp(28px,5vw,66px);line-height:1.1;
  text-align:center;padding:4px 10px;border:none;background:transparent;color:var(--ink)}
/* 下拉箭头脱离文字流，不然文字会被它挤得偏左。
   大小取中：钉成 15px 在这么大的查询框上小得看不见，完全不管又会跟着字号顶到
   66px、技能名一长就和它挤在一起。所以用 --arrow 单独给个约一半的上限。
   ⚠️ 这个伪元素的默认大小是按 font-size 算的（1em），只设 width/height 没用，
   必须连 font-size 和 background-size 一起给，四个属性得是同一个值。 */
#sk-q::-webkit-calendar-picker-indicator{position:absolute;right:14px;top:50%;
  font-size:var(--arrow);width:var(--arrow);height:var(--arrow);
  background-size:var(--arrow) var(--arrow);
  padding:0;margin:0;transform:translateY(-50%);opacity:.7}
#sk-q:hover{background:rgba(184,135,74,.06);cursor:pointer}
#sk-q:focus{outline:none;background:rgba(184,135,74,.1);cursor:text}
/* 资产参考表：一次只显示下拉里选中的那个时代 */
.era-bar{display:flex;align-items:center;gap:12px;margin:0 0 14px;flex-wrap:wrap}
.era-lab{font-size:13px;letter-spacing:.14em;color:var(--ink-dim)}
.era-sel{font:inherit;font-size:15px;color:var(--ink);background:var(--bg-soft);
  border:1px solid var(--line);border-radius:8px;padding:8px 12px;cursor:pointer}
.era-sel:hover{border-color:var(--accent)}
.era-sel:focus{outline:none;border-color:var(--accent)}
.era-sel option{background:var(--bg-panel);color:var(--ink)}
.q-in{--arrow:16px;   /* 下拉箭头多大，见下面那条 */
  position:relative;font:inherit;font-size:15px;color:var(--ink);
  background:var(--bg-soft);border:1px solid var(--line);border-radius:8px;
  padding:8px 34px 8px 12px;min-width:220px}
.q-in::placeholder{color:var(--ink-faint)}
.q-in:hover{border-color:var(--accent);background:rgba(184,135,74,.06);cursor:pointer}
.q-in:focus{outline:none;border-color:var(--accent);background:rgba(184,135,74,.1);
  cursor:text}
/* 箭头脱离文字流：内联排的话它跟着文字基线走，看着上紧下松。
   右侧 padding 给它腾出位置，否则占位文字会钻到箭头底下。
   居中为什么要多补一段位移，见上面 .edit-f input[list] 那条的说明——一回事。 */
.q-in::-webkit-calendar-picker-indicator{position:absolute;right:12px;top:50%;
  font-size:var(--arrow);width:var(--arrow);height:var(--arrow);
  background-size:var(--arrow) var(--arrow);
  transform:translateY(-50%) translateY(-6px);
  margin:0;padding:0;opacity:.7;cursor:pointer}
/* 成长表上面那条横栏：左边找属性/技能，右边按月筛选，中间一根竖线隔开 */
.mo-bar{display:flex;align-items:center;gap:9px;margin:0 0 14px;flex-wrap:wrap}
.mo-sep{width:1px;align-self:stretch;min-height:24px;background:var(--line);margin:0 5px}
/* 这一排（两个标签 + 两个框 + 共几行 + 四个筛选钮 + 提示 + 加一个月）要铺满正文宽：
   剩下的横向空间全归两个输入框（flex-grow），末尾的「＋ 加一个月」自然顶在最右边。
   ⚠️ 两处别写错，写错了钮就掉到第二行去：
   1. **别在 .gr-month 上写 margin-left:auto** —— auto 外边距比 flex-grow 先分空间，
      钮是贴右了，两个框却再也长不了，中间空一大块。
   2. **flex-basis 要写小**（120 / 140，不是它们平时的宽度）—— 换行是按 basis 算的
      （先分行、后压缩），basis 写成想要的宽度，一出筛选提示这排就装不下、当场换行。 */
.mo-bar #gr-q{flex:1 1 120px;min-width:120px}
.mo-bar #mo-q{flex:1 1 140px;min-width:140px}
/* 筛选提示（只在有话说时才有字）挤在「＋ 加一个月」左边，地方从两个框身上匀：
   min-width:0 才肯让 flex 压缩它，超长就省略号，全文挂在 title 上
  （成长表-月份筛选.js 写字时一并写 title）。不这么写的话，一出提示整排就换行、
   钮掉到第二行去。 */
.mo-bar #mo-note{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mo-btns{display:flex;gap:6px;flex-wrap:wrap}
.mo-btn{font:inherit;font-size:13px;letter-spacing:.06em;color:var(--ink-dim);
  background:var(--bg-soft);border:1px solid var(--line);border-radius:7px;
  padding:7px 12px;cursor:pointer}
.mo-btn:hover{border-color:var(--accent);color:var(--ink);
  background:rgba(184,135,74,.08)}
.mo-note{font-size:13px;letter-spacing:.04em;color:var(--ink-faint)}
/* 被筛掉的月份列 / 行。td、tr 有自己的 display，得手动盖掉 hidden */
.sheet td[hidden]{display:none}
.sheet tr[hidden]{display:none}
.era-pane .sheet td{vertical-align:middle;padding:9px 12px;font-size:14px}
.era-note{margin:10px 0 0;font-size:13px;color:var(--ink-dim);line-height:1.7}
.price-note{margin:0 0 14px}
/* 生活水平详述 / 英制单位：并排两栏，整页宽度和资产参考表一致 */
/* 两栏拉成一样高，不然右边那张短的下沿吊在半空 */
.col2{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:stretch}
.col2 .sheet-wrap{height:100%}
.col2 .sheet td{max-width:none;padding:10px 14px;line-height:1.75}
/* 物价参考表：每个分类一张表。高矮差太多，用分栏流式排，不留大片空白。
   外面不再套一层框——表格自己那圈边就是框，套两层反而显得局促 */
.price-grid{columns:2;column-gap:16px}
.price-card{break-inside:avoid;-webkit-column-break-inside:avoid;display:inline-block;
  width:100%;margin:0 0 22px}
/* display 是自己写的，得显式压过 UA 的 [hidden]，不然搜索时空框还杵在那 */
.price-card[hidden]{display:none}
.sheet td.price-cap,.sheet td.attr-cap{background:var(--bg-strong);font-size:15px;
  font-weight:600;text-align:center;letter-spacing:.1em;color:var(--accent-soft);
  padding:9px 10px}
.price-grid .sheet td{max-width:none;padding:5px 10px}
/* 属性注释：八张表两栏排。这里不用分栏流式——那样左右两列会各排各的、错开半张表，
   改成真正的网格，左右两张表从同一条线开始，十二档也就逐行对齐。
   顶端对齐而不是拉成等高：敏捷和教育多出表尾三栏，等高只会给旁边那张表
   底下留一条空板子，让它自然往下长更干净 */
/* 同一行的两张卡拉到一样高，底边对齐：卡片本身被 grid 撑满（默认的 stretch），
   里面的表格再撑满卡片，多出来的高度摊到各行上——差个十几像素摊到十几行，
   一行还不到 1px，看不出来。靠给某张卡多打一行空行是对不齐的：行高和文字
   行高本来就不一样，而且窗口一窄文字换行，差多少又变了。 */
.attr-grid{display:grid;grid-template-columns:1fr 1fr;gap:22px 16px}
.attr-card{min-width:0;display:flex;flex-direction:column}
.attr-card>.table-wrap{flex:1}
.attr-grid .sheet.full{height:100%}
/* 属性阶梯是整句话，行距松一点；数值那列窄，说明那列吃掉剩下的宽度 */
.attr-grid .sheet td{max-width:none;padding:7px 11px;line-height:1.75}
.attr-grid .sheet td.nw{width:1%}
.sheet td.note{white-space:pre-wrap;color:var(--ink-dim);text-align:left}
@media(max-width:760px){
  .col2{grid-template-columns:1fr}
  .price-grid{columns:1}
  .attr-grid{grid-template-columns:1fr}
}
.sheet td.right{text-align:right}
.sheet tr:hover td{background:rgba(184,135,74,.06)}

.bg-grid{display:grid;gap:10px;grid-template-columns:1fr}
.bg-item{background:var(--bg-panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 14px}
.bg-k{font-size:12px;letter-spacing:.14em;color:var(--ink-dim);margin-bottom:4px}
.bg-v{font-size:14px;overflow-wrap:anywhere}
.key-badge{margin-left:8px;font-size:10px;letter-spacing:.1em;color:var(--bg);
  background:var(--accent);border-radius:3px;padding:1px 5px}
.story{background:var(--bg-panel);border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:var(--radius);padding:16px 18px;font-size:15px;white-space:pre-wrap;margin-top:10px}

/* 页脚。FOOTER_TEXT 留空时这里只剩正文底下那条横线 */
footer{margin-top:48px;padding-top:16px;border-top:1px solid var(--line);
  color:var(--ink-faint);font-size:12px}
footer span{display:block}
/* 素材来源那行比署名再淡一档：该有，但不抢版面 */
footer .foot-src{margin-top:5px;font-size:11px;opacity:.7;line-height:1.6}
/* 备案号：链接得看得出是链接，但别抢眼；打印时也留着 */
footer .foot-beian{margin-top:6px;font-size:11px;line-height:1.6}
footer .foot-beian a{color:var(--ink-faint);text-decoration:none}
footer .foot-beian a:hover{color:var(--accent-soft);text-decoration:underline}

@media (max-width:820px){
  .attr-panel{grid-template-columns:1fr}
}
/* 窄屏放不下「球-半圆-球」这一排：摞成一列，球居中（它是个圆，拉不得），
   半圆压矮一点免得占掉整屏 */
@media (max-width:760px){
  .study-row{grid-template-columns:1fr;justify-items:center}
  .act-arc{max-width:none;height:170px}
  .arc-v{font-size:21px}
  .arc-day{font-size:38px}
  .arc-date{font-size:16px}
  /* 摞成一列之后，「几年几月」那行绝对定位在半圆外面、不占地方，会压到底下
     那个球的小标题上。宽屏时它落在 .study-row 底下那 40px 里，窄屏得自己留 */
  .arc-col{margin-bottom:44px}
}
@media (max-width:560px){
  .wrap{padding:18px 14px 48px}
  /* 正文在窄屏收到 14px，导航条跟着收，金条才继续和大名对齐 */
  .nav-inner{padding:0 14px}
  .skill-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
  /* 原版那一档（9×3、13、21）同样乘 1.2 */
  .attr-table th,.attr-table td{padding:10.8px 3.6px}
  .attr-table .a-label{font-size:15.6px}
  .attr-table .a-num{font-size:25.2px}
  /* 资产抬头竖过来：竖线换成横线，主次还在 */
  .asset-head{grid-template-columns:1fr;gap:14px;padding:14px}
  .ah-cr{padding:0 0 14px;border-right:0;border-bottom:1px solid var(--line)}
  .ah-figs,.ah-nocr .ah-figs{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 20px}
}
/* ---- 调查员档案页（index.html）单独放大 15% ----
   只挂在 body.page-index 上，其他四个参考页不受影响。
   属性表和雷达图不吃这 15%：那块自己按原版等比放大过 1.2 倍，规则写在上面属性表那一段。 */
.page-index .eyebrow{font-size:14px}
.page-index h1{font-size:clamp(32px,5.75vw,51px)}
.page-index .meta{font-size:16px}
.page-index h2{font-size:30px}
.page-index .note{font-size:15px}
/* 「总点数」那行跟着属性表一起等比放大（13 × 1.2） */
.page-index .attr-side .note{font-size:15.6px}
.page-index .empty{font-size:15px}

.page-index .stat-k{font-size:13px}
.page-index .stat-v{font-size:17px}
.page-index .stat-v .big{font-size:30px}
.page-index .stat-note{font-size:14px}

/* 技能卡：正文宽度下固定一行七个（不用 auto-fill，免得差几像素就掉成六个）。
   格子窄了，内边距和数值字号跟着收，技能名由 SKILL_FIT_JS 逐张量着放。
   窗口不够宽时退回按宽度自动排，列数少了名字才不至于挤成一团 */
.page-index .skill-grid{grid-template-columns:repeat(7,minmax(0,1fr))}
.page-index .rskill{padding:14px 9px}
.page-index .skill-name{font-size:17px}
.page-index .star{font-size:14px}
.page-index .skill-val,.page-index .rskill.tag::after{font-size:22px}
.page-index .tag-plus{font-size:22px}

.page-index .sk-tip{font-size:20px}
.page-index .sk-tip .tip-band{font-size:16px}
.page-index .sk-tip .tip-desc{font-size:18px}
.page-index .sk-tip .tip-more{font-size:17px}

.page-index .modal-x{font-size:34px}
.page-index .d-name{font-size:34px}
.page-index .d-stat-k{font-size:16px}
.page-index .d-stat-v{font-size:34px}
.page-index .d-desc{font-size:18px}
.page-index .d-desc-t{font-size:17px}
.page-index .d-ladder{font-size:18px}
.page-index .d-ladder th{font-size:17px}
.page-index .d-source{font-size:17px}

.page-index table.grid{font-size:15px}
.page-index .grid th{font-size:14px}

.page-index .bg-k{font-size:14px}
.page-index .bg-v{font-size:16px}
.page-index .key-badge{font-size:12px}
.page-index .story{font-size:17px}

.page-index footer{font-size:14px}

@media (max-width:1040px){
  .page-index .skill-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
}
@media (max-width:560px){
  .page-index .skill-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}
}

/* ---- 成长表：表格自己滚，前四列和头两行钉住 ----
   页面本身不再左右晃（导航、标题、筛选按钮都待着不动），
   滚动条用下面那段脚本挪到表格上边，不用滚到表尾去找。 */
.page-growth .sheet-wrap{width:auto;max-width:100%;overflow-x:auto;
  overflow-y:visible}
.page-growth .sheet{width:max-content;min-width:100%}
/* 头两行：大标题和表头 */
.page-growth .sheet tr.g-title td,
.page-growth .sheet tr.g-head td{position:sticky;z-index:3}
.page-growth .sheet tr.g-title td{top:0}
.page-growth .sheet tr.g-head td{top:var(--g-head-top,42px)}
/* 前四列：属性/技能、成长+初始、总计成长、初始。
   「内容经历」那块（g-memo）整块跳过：它的格子带 rowspan/colspan，
   宽度和列对不上，钉住就会和右边的示例列叠在一起、字压字。
   那块本来就是说明文字，横滚时跟着走反而正常。 */
/* 只写 position，不碰 background——底色各行本来就有自己的规则，
   在这里统一刷一遍会把表头那两行的颜色顶掉 */
.page-growth .sheet tr > td:nth-child(-n+4):not([colspan]){
  position:sticky;z-index:2}
/* 「内容经历」那两格照样钉住，但只钉带 rowspan 的那两个：
   第一格是列1，第二格 colspan=3 正好盖住列2-4，合起来恰好是冻结区，
   不会探到右边的示例列上去。g-memo 后面几行的头一格其实已经是「示例」
   那一列了（列5），按 nth-child 去钉就会把它拽到最左边、和列1字压字——
   这也是之前整块跳过它的原因。 */
.page-growth .sheet tr.g-memo > td[rowspan]{position:sticky;z-index:2}
.page-growth .sheet tr.g-memo > td[rowspan]:nth-child(1){left:0}
.page-growth .sheet tr.g-memo > td[rowspan]:nth-child(2){left:var(--g-c1,0px)}
.page-growth .sheet tr.g-memo > td:not([rowspan]){position:static;left:auto}
.page-growth .sheet tr > td:nth-child(1){left:0}
.page-growth .sheet tr > td:nth-child(2){left:var(--g-c1,0px)}
.page-growth .sheet tr > td:nth-child(3){left:var(--g-c2,0px)}
.page-growth .sheet tr > td:nth-child(4){left:var(--g-c3,0px)}
/* g-title 那行第一格 colspan=4，一格就盖满了整个冻结区；它后面的格子
   其实已经是第 5 列往后了。上面那几条按 nth-child 派 left，会把第 2、3 格
   也钉进冻结区，横滚时压在标题上（实测横滚 430px 后它们从 x=498/764
   跑到 198/334）。所以这一行只有第一格横向钉住，其余的把 left 交回去，
   position 仍是 sticky——竖向吸顶那部分还要留着。 */
.page-growth .sheet tr.g-title > td:nth-child(n+2){left:auto;z-index:3}
/* 那句提示：格子横跨「示例」+ 所有月份列（成长表.py 里并的），里头再套一层
   sticky 的 span，把话钉在可视区正中——格子跟着表格滚出去，字不跟着走。
   左边钉在冻结区右沿（--g-c4 = 前四列的累计宽度），宽度取可视区去掉冻结区
   剩下的那一段（--g-vis）；两个值都由 成长表-冻结表头.js 的 measure() 量。
   max-width 交给格子兜底：显示的月份少、格子比可视区还窄时它跟着缩，
   不会探到格子外面去。padding 归 span，格子自己不留，左边界才和冻结区严丝合缝。 */
.page-growth .sheet td.g-tipcell{padding-left:0;padding-right:0}
.page-growth .sheet .g-tip{position:sticky;display:block;text-align:center;
  padding:0 10px;left:var(--g-c4,0px);width:var(--g-vis,100%);max-width:100%}
/* 月份只剩一两列时这句话会被挤成一根竖条——藏字不藏格子：
   格子还占着「示例」那一列，标题行的底色就不会缺一块 */
.page-growth .sheet td.mo-thin .g-tip{display:none}
/* 行列交叉那几格要压在最上面，否则滚动时互相盖 */
.page-growth .sheet tr.g-title > td:nth-child(1),
.page-growth .sheet tr.g-head > td:nth-child(-n+4){z-index:4}
/* 冻结区的外沿再压一条实线：底下滚过来的字正好被边界切一半，
   露出来的那一小条很扎眼。谁是最右一格要按行分——普通行是第 4 格，
   g-title 是那个 colspan=4 的第 1 格，g-memo 是带 rowspan 的第 2 格。 */
.page-growth .sheet tr:not(.g-title):not(.g-memo) > td:nth-child(4),
.page-growth .sheet tr.g-title > td:nth-child(1),
.page-growth .sheet tr.g-memo > td[rowspan]:nth-child(2){
  box-shadow:2px 0 0 0 var(--line)}
/* 钉住的格子得有不透明底色，不然下面的内容会透上来 */
.page-growth .sheet tr.g-attr > td:nth-child(-n+4),
.page-growth .sheet tr.g-row > td:nth-child(-n+4){background:var(--bg-panel)}

/* g-title / g-head 的底色下面本来就有规则，不重复写 */
/* 这张表不能用 border-collapse:collapse。合并之后那 1px 边框归表格所有、
   不归格子，格子的背景也不覆盖它；冻结列钉住不动，那条线却跟着表格滚走，
   留下一道没人画的缝——下层的字就从缝里透出来。
   改成 separate + spacing 0：边框归各自的格子，跟着格子一起钉住，缝也就没了。
   每格只画右边和下边，最左一列补左边、最上一行补上边，合起来还是原来那张 1px 网格。 */
.page-growth .sheet{border-collapse:separate;border-spacing:0}
.page-growth .sheet td{border-width:0 1px 1px 0}
.page-growth .sheet tr > td:first-child{border-left-width:1px}
.page-growth .sheet tr:first-child > td{border-top-width:1px}
/* 浮动表头：头两行的一份克隆，页面往下滚时钉在导航底下。
   overflow:hidden 既裁掉多余的部分，又让它成为一个可以用脚本设 scrollLeft
   的滚动容器——里头前四列那套 sticky 才照样钉得住。
   表格本身完全没动，这一层纯粹是影子。 */
.g-float{position:fixed;overflow:hidden;z-index:8;display:none;
  box-shadow:0 8px 16px rgba(0,0,0,.5)}
.g-float table{margin:0}
/* 表格上方的滚动条：和表格同宽的一条代理，拖它就等于拖表格。
   它自己也是 sticky，跟浮动表头一起钉在导航底下——页面滚多远都够得着。 */
.g-scroll{overflow-x:auto;overflow-y:hidden;margin:0 0 6px;
  position:sticky;top:var(--nav-h,75px);z-index:7;background:var(--bg)}
.g-scroll > div{height:1px}
.sheet-wrap::-webkit-scrollbar,.g-scroll::-webkit-scrollbar{height:10px}
.sheet-wrap::-webkit-scrollbar-track,
.g-scroll::-webkit-scrollbar-track{background:var(--bg-soft);border-radius:5px}
.sheet-wrap::-webkit-scrollbar-thumb{background:#4a4034;border-radius:5px}
.sheet-wrap::-webkit-scrollbar-thumb:hover{background:var(--accent)}
/* 代理条的滑块一直是亮的，不用等鼠标移上去 */
.g-scroll::-webkit-scrollbar-thumb{background:var(--accent);border-radius:5px}

/* ---- 成长表页：最上面三段分色，和下面一排排技能行拉开 ---- */
.page-growth .sheet tr.g-title td{background:var(--bg-strong);color:var(--accent-soft);
  font-weight:600;letter-spacing:.1em}
.page-growth .sheet tr.g-head td{background:#3a3126;color:var(--ink);
  font-weight:600;letter-spacing:.08em;white-space:nowrap}
/* 成长表整张表都不吃 Excel 的填色（那套浅蓝是照空白卡来的，搬到深色页面上
   会变成忽明忽暗的竖条），底色统一交给下面这几条。属性行只把名字挑成强调色。 */
.page-growth .sheet tr.g-attr td:first-child{color:var(--accent-soft);font-weight:600}
/* 「模组内容经历」那块：淡色只留给左边那两个合并格——Excel 里也只有这两格
   有底色，右边的示例、月份列跟下面的技能行长一个样 */
.page-growth .sheet tr.g-memo td[rowspan]{
  /* 这两格要钉住，底色就不能是半透明的——下层滚过去会透上来。
     那层金色薄膜改成画在不透明面板色上，颜色和以前一模一样 */
  background-color:var(--bg-panel);
  background-image:linear-gradient(rgba(184,135,74,.11),rgba(184,135,74,.11));
  color:var(--ink-dim);
  /* 这两格跨五行，文字堆在顶上会吊着一大片空板子——竖着也居中，字号跟着放大 */
  vertical-align:middle;line-height:1.9}
.page-growth .sheet tr.g-memo td[rowspan]:first-child{font-size:16px;
  letter-spacing:.08em;color:var(--accent-soft)}
.page-growth .sheet tr.g-memo td[rowspan][colspan]{font-size:15px;padding:6px 22px}
.page-growth .sheet tr.g-memo td:not([rowspan]){background:transparent}
/* 「示例」列的句子较长，给够宽度让它在自己格子里折行，不再往月份列上压 */
.page-growth .sheet td.wide{min-width:210px}
/* 还空着的月份列：留一个能落笔的宽度，不然细成一条缝 */
.page-growth .sheet td{min-width:66px}

@media print{
  :root{--bg:#fff;--bg-panel:#fff;--bg-soft:#f4f1ea;--bg-strong:#e5ded0;--line:#c9c1b4;
    --ink:#1a1a1a;--ink-dim:#555;--ink-faint:#888;--accent:#8a5c22;--accent-soft:#8a5c22;
    --water:#3d7f90;--water-lit:#7cc3d3}
  body{background:#fff}
  .nav{display:none}
  .wrap{max-width:none;padding:0}
  section,.skill,.stat,.bg-item,.attr-panel,.study-row,
  .asset-head{break-inside:avoid}
  .r-area{fill:rgba(138,92,34,.28)}
}
