/* ============================================================
   ADAM ZHANG — 全站样式
   灰阶舞台 + 强调色跟着角色走
   字体：Plus Jakarta Sans（标题）+ Newsreader（正文）+ JetBrains Mono（小标签）
   ============================================================ */
:root{
  --paper:#FAFAF8; --surface:#F0F0EC; --line:#E0E0DA; --line2:#C8C8C1;
  --muted:#6B6B6E; --ink:#17171A; --black:#0A0A0C;
  --silver:#C9CCD1; --gold:#C8A96A;

  --acc:#17171A; --acc-t:#17171A; --acc-soft:#17171A12;

  --r:16px; --rl:22px;
  padding-right:0;
  --disp:'Plus Jakarta Sans','Noto Sans SC',sans-serif;
  --dw:800; --dls:-.03em;
  --sans:'Newsreader','Noto Sans SC',Georgia,serif;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  --ease:cubic-bezier(.22,1,.36,1);
  --rail:clamp(168px,14vw,208px);
}
[data-accent="ink"]     {--acc:#17171A;--acc-t:#17171A;--acc-soft:#17171A12}
[data-accent="career"]  {--acc:#3A4E78;--acc-t:#3A4E78;--acc-soft:#3A4E7814}
[data-accent="academic"]{--acc:#6E9CC4;--acc-t:#3E6E99;--acc-soft:#6E9CC422}
[data-accent="hoops"]   {--acc:#2F7D57;--acc-t:#276848;--acc-soft:#2F7D5716}
[data-accent="football"]{--acc:#C8A96A;--acc-t:#8A6F2A;--acc-soft:#C8A96A28}
[data-accent="trumpet"] {--acc:#6B4E9E;--acc-t:#6B4E9E;--acc-soft:#6B4E9E16}
/* Adam 2026-08-09 新增：内容创作。色板里原本没有暖红这一支——
   藏蓝 / 浅蓝 / 绿 / 金 / 紫全是冷色或中性暖，内容创作夹在职业和学术之间，
   需要一个一眼分得出来的色。#B0573C 对纸色 4.7:1 过 AA，
   文字调 #9A4A31 是 5.9:1 —— 和橄榄球金那套「亮色做块、深调做字」结构一致。 */
[data-accent="creator"] {--acc:#B0573C;--acc-t:#9A4A31;--acc-soft:#B0573C1C}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.68;-webkit-font-smoothing:antialiased;
}
/* Adam 2026-08-23：首页原先在右边留出一整条 168–208px 给 Q 版形象站，
   body 一被 padding 掉，居中的 .wrap 就跟着整体左移约 100px——
   这是首页和其它 30 个页面对不齐的唯一原因。
   现在不留位了：Q 版改成浮在内容之上的挂件（.rail 本来就是 position:fixed），
   首页的 .wrap 和其它页面走同一套居中规则。 */
body.has-rail{padding-right:0}
.has-rail .foot{margin-right:0;padding-right:0}
h1,h2,h3,h4{font-family:var(--disp);font-weight:var(--dw);letter-spacing:var(--dls);line-height:1.05;margin:0}
a{color:inherit}
button{font:inherit;cursor:pointer}
img{max-width:100%;display:block}
.wrap{max-width:1120px;margin:0 auto;padding-inline:36px}
.mono{font-family:var(--mono)}

/* ================= NAV ================= */
.nav{position:sticky;top:0;z-index:100;background:rgba(250,250,248,.88);backdrop-filter:blur(14px) saturate(1.3);border-bottom:1.5px solid var(--line)}
.nav__in{max-width:none;margin:0;padding:13px clamp(20px,3.4vw,46px);display:flex;align-items:center;gap:18px}
/* 首页导航栏原来要往右侧留位里冲一段（margin-right 负值 + padding-right 半条），
   那是给 body 的 padding 做补偿用的。留位取消，补偿一起撤，
   首页导航和其它页面完全同一套。（Adam 2026-08-23） */
.brand{display:flex;align-items:center;gap:10px;text-decoration:none}
/* 标志：Adam 自己的手写 A。缎带颜色跟着页面主题走，首页滚动时实时换 */
.brand__m{width:39px;height:30px;flex:0 0 39px;display:block;
  background:no-repeat left center/contain url(img/mark-ink.png)}
[data-accent="career"]   .brand__m{background-image:url(img/mark-career.png)}
[data-accent="academic"] .brand__m{background-image:url(img/mark-academic.png)}
[data-accent="hoops"]    .brand__m{background-image:url(img/mark-hoops.png)}
[data-accent="football"] .brand__m{background-image:url(img/mark-football.png)}
[data-accent="trumpet"]  .brand__m{background-image:url(img/mark-trumpet.png)}
.brand__t{font-family:var(--disp);font-weight:var(--dw);font-size:17px;letter-spacing:var(--dls)}
.nav__links{margin-left:auto;display:flex;gap:2px;align-items:center}
.nav__links>a,.drop__btn{
  font-family:var(--disp);font-weight:600;font-size:14px;text-decoration:none;color:var(--muted);
  padding:8px 12px;border-radius:10px;border:0;background:transparent;transition:.2s var(--ease);
  display:inline-flex;align-items:center;gap:5px
}
.nav__links>a:hover,.drop__btn:hover{color:var(--ink);background:var(--surface)}
.nav__links>a.on,.drop.on .drop__btn{color:var(--ink)}
.nav__links>a.on::after{content:"";width:5px;height:5px;border-radius:50%;background:var(--acc)}
.drop.on .drop__btn::after{content:"";width:5px;height:5px;border-radius:50%;background:var(--acc)}
.nav__links>a.cta{
  font-weight:700;font-size:13.5px;background:var(--ink);color:var(--paper);
  padding:9px 16px;border-radius:999px;box-shadow:0 3px 0 rgba(0,0,0,.25);margin-left:8px
}
.nav__links>a.cta:hover{background:var(--ink);color:var(--paper);transform:translateY(-1px)}
/* 简历按钮原来在首页要 translateX(50%) 才对得上形象中心——同样是留位的补偿，
   一并撤掉。（Adam 2026-08-23） */
.drop{position:relative}
.drop__menu{
  position:absolute;top:calc(100% + 8px);left:0;min-width:212px;background:var(--paper);
  border:1.5px solid var(--line);border-radius:var(--rl);padding:6px;
  box-shadow:0 6px 0 rgba(23,23,26,.06),0 18px 40px rgba(23,23,26,.10);
  opacity:0;visibility:hidden;transform:translateY(-6px);transition:.22s var(--ease)
}
.drop:hover .drop__menu,.drop:focus-within .drop__menu{opacity:1;visibility:visible;transform:none}
.drop__menu a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:11px;text-decoration:none;
  font-size:14px;font-weight:600;font-family:var(--disp);color:var(--ink)}
.drop__menu a:hover{background:var(--surface)}
.dotc{width:10px;height:10px;border-radius:4px;flex:none;box-shadow:0 2px 0 rgba(0,0,0,.14)}

/* ================= 右侧角色栏（无虚线） ================= */
.rail{position:fixed;right:0;top:0;bottom:0;width:var(--rail);z-index:90;pointer-events:none}
/* Adam 2026-08-06：Q 版形象固定在屏幕右下角，并且比原先小一号。
   出现逻辑（哪一段出哪个形象）完全不变，只改位置和尺寸；
   位置是定死的，不再随滚动上下移动（site.js 里那段 top 计算已同步删掉）。 */
/* Adam 2026-08-23：首页取消右侧留位之后，Q 版站的是内容之上，不再是专属空隙。
   人物宽度改成跟着视口连续缩放（原来 84–104px 定死），
   窄屏时缩到 64px，宽屏仍回到 104px，不做断点跳变。 */
.rail__char{position:absolute;left:auto;right:16px;top:auto;bottom:18px;
  transform:none;width:clamp(76px,6.6vw,104px)}
.rail__char{pointer-events:auto}
/* 聊天框是撞得最狠的一块（1280 下人物已经让开、它还压着插画 69px）。
   宽度和字号一起跟视口缩：窄屏 11px / 约 88px 宽，宽屏回到 12.5px / 196px。 */
.railbub{position:absolute;bottom:calc(100% - 16px);right:-8px;z-index:2;
  width:max-content;max-width:min(196px,7.4vw);
  background:var(--paper);color:var(--ink);border:2px solid var(--ink);
  border-radius:14px 14px 14px 4px;padding:8px 12px;text-align:left;
  font-family:var(--disp);font-weight:700;font-size:clamp(11px,.95vw,12.5px);line-height:1.34;
  letter-spacing:-.01em;cursor:pointer;
  box-shadow:0 3px 0 rgba(23,23,26,.16);transition:transform .25s var(--ease)}
.railbub:hover{transform:translateY(-2px)}
.railbub::before,.railbub::after{content:"";position:absolute;border-style:solid}
.railbub::before{right:14px;bottom:-15px;
  border-width:15px 0 0 13px;border-color:var(--ink) transparent transparent transparent}
.railbub::after{right:17px;bottom:-11px;
  border-width:11px 0 0 9px;border-color:var(--paper) transparent transparent transparent}
.railfig{width:100%;aspect-ratio:3/4;
  background:no-repeat center bottom/contain url(img/chibi-hoodie.png);
  filter:drop-shadow(0 14px 18px rgba(23,23,26,.13));
  transition:opacity .35s var(--ease)}
[data-accent="career"]   .railfig{background-image:url(img/chibi-business.png)}
[data-accent="academic"] .railfig{background-image:url(img/chibi-graduation.png)}
[data-accent="hoops"]    .railfig{background-image:url(img/chibi-basketball.png)}
[data-accent="football"] .railfig{background-image:url(img/chibi-football.png)}
[data-accent="trumpet"]  .railfig{background-image:url(img/chibi-trumpet.png)}
/* Adam 2026-08-23：creator 用说唱形象（他自己给的图）。
   这一条同时管两处：More of Me 页，以及**首页 Content Creator 那一段**
   （HOME_SECS 里 acc='creator'）。 */
[data-accent="creator"] .railfig{background-image:url(img/chibi-rap.png)}
/* ⚠️ 说唱那张图带麦克风架，长宽比 1.03，其余形象约 0.65。
   在同一个 3:4 的框里按 contain 缩放，它只能撑到 81px 高，比别人矮 28%。
   所以只在这个形象出现时把框放宽，让**高度**和其余形象对齐（宽 ÷ 1.03 ≈ 标准高）。

   ⚠️⚠️ `:not([data-fig])` 这一段不能省。加宽必须跟着**那张图**走，不能跟着主题色走 ——
   Stories 的 More of me 段主题色也是 creator，但它用 data-fig="hello" 换成了连帽衫。
   少了这个限定，它会把加宽一起继承过去：框变成 116×177，而 contact 是 84×135，
   大 38%。（2026-08-24 Adam 指出，这是上一轮埋进去的） */
html[data-accent="creator"]:not([data-fig]) .rail__char{width:clamp(105px,9.1vw,144px)}
/* 故事段和联系段的主题色都是墨黑，所以单独用 data-fig 指定形象 */
/* ⚠️ 这两条只挂在 <html> 上（JS 的 paint() 写的那个），**不能写成裸的 [data-fig]**。
   stories.html 的 <body> 上也有 data-fig="stories" —— 但那个是给导语排版用的
   （body[data-fig="stories"] .band .lead 那几条），不是给形象用的。
   写成裸选择器的话，body 那个会盖住分段自己的 [data-accent]，
   整页四段全变成同一个形象。（这一轮真踩到了。） */
html[data-fig="stories"] .railfig{background-image:url(img/chibi-trumpetkid.png)}
html[data-fig="contact"] .railfig{background-image:url(img/chibi-flagfootball.png)}
/* Adam 2026-08-23：分段级的形象覆盖。用在主题色和形象对不上的地方 ——
   Stories 的 Sportsmanship 段主题色是 hoops（绿）但要橄榄球形象，
   More of me 段主题色是 creator 但要 Hello。
   ⚠️ 必须排在上面 [data-accent] 那几条**之后** —— 两边都是 (0,2,0)，
   同分靠先后决定，写在前面等于没写。（坑 #1） */
html[data-fig="football"] .railfig{background-image:url(img/chibi-football.png)}
html[data-fig="hello"]    .railfig{background-image:url(img/chibi-hoodie.png)}
/* 页级的形象覆盖，写在 <body> 上，只管形象、不碰布局。
   contact 页必须留着 data-fig="contact"（那个值管整屏居中布局，
   而且全站每个页脚都挂着它），所以形象只能靠这条 (0,2,1) 压过去。 */
body[data-figure="hoodie"]       .railfig{background-image:url(img/chibi-hoodie.png)}
body[data-figure="flagfootball"] .railfig{background-image:url(img/chibi-flagfootball.png)}
body[data-figure="recording"]    .railfig{background-image:url(img/chibi-recording.png)}
.on-dark .charlab{color:#9A9AA2}

.charlab{transition:color .4s var(--ease);font-family:var(--disp);font-weight:700;font-size:9px;letter-spacing:.1em;color:var(--muted);text-align:center;margin-top:7px;text-transform:uppercase}

/* ================= AGENT 入口（没有侧栏的页面） ================= */
.agentdock{position:fixed;right:26px;bottom:26px;z-index:95;
  display:flex;align-items:center;gap:9px;
  background:var(--paper);color:var(--ink);border:2px solid var(--ink);
  border-radius:16px 16px 4px 16px;padding:9px 15px 9px 12px;
  font-family:var(--disp);font-weight:700;font-size:12.5px;letter-spacing:-.01em;
  cursor:pointer;box-shadow:0 3px 0 rgba(23,23,26,.18);
  transition:transform .25s var(--ease),box-shadow .25s var(--ease)}
.agentdock:hover{transform:translateY(-2px);box-shadow:0 5px 0 rgba(23,23,26,.18)}
.agentdock .brand__m{width:30px;flex:0 0 30px;height:23px}
@media (max-width:700px){.agentdock{right:14px;bottom:14px;font-size:12px}}
/* 兜底药丸：全站每页都有一颗，在各自的门槛以下顶替右下角入口。
   （Adam 2026-08-23：右下角入口全站统一 —— **只有首页带 Q 版形象**，
   其余页面只要气泡和文字。两种的门槛不一样，靠 body 上的 has-bare 区分。）

   首页 ≥1200：Q 版 + 气泡。<1200 换药丸 ——
     门槛原本 1150，插画统一到 contact 的 420px 之后右边少了 25px，
     实测只能压到 1200（1190 时气泡余量剩 2.6px、1180 就负了）。
     气泡宽度同时从 8.2vw 收到 7.4vw 换来这 10px。
     1200 是能保住 Adam 自己 1210 窗口的最低门槛，别再往下压。
   其余页面 ≥981：只有气泡。没有形象就没有那个横向冲突，门槛可以低很多。
     ≤980 换药丸：窄屏上一个竖着的三行气泡太占地方。 */
.agentdock--fb{display:none}
@media (max-width:1199px){
  .has-rail:not(.has-bare) .rail{display:none}
  .has-rail:not(.has-bare) .agentdock--fb{display:flex}
}
@media (max-width:980px){
  .has-bare .rail{display:none}
  .has-bare .agentdock--fb{display:flex}
}
/* 没有形象时，气泡原本挂在形象上方（bottom:calc(100% - 16px)），
   形象一撤那个定位就没了参照物。改成气泡自己就是那个盒子。
   ⚠️ right/bottom 这两个数是量出来的，不是随手给的：
   气泡贴视口右下角之后会压到 contact / experience 主插画的右下角，
   981–1210 之间实测最多压住 61×43px。往右靠只能补 8px，不够；
   真正让开的办法是**贴到最角上**（16/16），让它落在插画脚下那块空白里。 */
.rail--bare .rail__char{width:auto;height:auto;right:16px;bottom:16px}
.rail--bare .railbub{position:static;display:block}

/* ================= 旧 AGENT DOCK ================= */
.dock{position:fixed;right:calc(var(--rail) + 8px);bottom:24px;z-index:95;display:flex;align-items:flex-end;gap:10px}
.dock__bub{background:var(--paper);border:2px solid var(--ink);border-radius:16px 16px 4px 16px;padding:10px 14px;
  font-family:var(--disp);font-weight:600;font-size:13.5px;max-width:200px;box-shadow:0 4px 0 rgba(23,23,26,.18);
  animation:pop .5s var(--ease)}
@keyframes pop{from{opacity:0;transform:translateY(6px) scale(.96)}to{opacity:1;transform:none}}
.dock__av{width:62px;height:62px;border-radius:20px;background:var(--acc);color:#fff;border:0;display:grid;place-items:center;
  text-align:center;line-height:1.15;font-family:var(--disp);font-weight:700;font-size:11.5px;
  box-shadow:0 4px 0 rgba(0,0,0,.22);transition:.25s var(--ease)}
[data-accent="football"] .dock__av{color:#3A2E12}
.dock__av:hover{transform:translateY(-3px)}

/* ================= 通用块 ================= */
section{padding-block:clamp(56px,8vw,104px);position:relative}
/* Adam 2026-08-25：首页各板块之间的留白减半。
   ⚠️ 只作用于首页（.has-rail:not(.has-bare)）—— 全站 section 的这个值
   是内页页眉、故事卡、长文共用的，改全局会把每一页都压扁。
   首页板块多、每块自带标题和插图，原来的 8vw 在首页显得过空。 */
.has-rail:not(.has-bare) .band{padding-block:clamp(28px,4vw,52px)}
.band{border-top:1.5px solid var(--line)}
.eyebrow{display:inline-flex;align-items:center;gap:9px;font-family:var(--disp);font-weight:700;font-size:11.5px;letter-spacing:.19em;
  text-transform:uppercase;color:var(--acc-t);margin-bottom:16px}
.eyebrow i{width:22px;height:2px;background:var(--acc);border-radius:2px;font-style:normal}
h2{font-size:clamp(28px,4.4vw,48px)}
h3{font-size:clamp(19px,2.3vw,24px)}
.lead{font-size:clamp(16px,1.7vw,18.5px);line-height:1.72;color:#43434A;max-width:58ch;margin:16px 0 0}
.btns{display:flex;gap:10px;flex-wrap:wrap;margin-top:26px}
.btn{font-family:var(--disp);font-weight:700;font-size:13.5px;text-decoration:none;padding:13px 22px;border-radius:999px;
  border:0;display:inline-flex;align-items:center;gap:7px;transition:.2s var(--ease)}
.btn--p{background:var(--acc);color:#fff;box-shadow:0 4px 0 rgba(0,0,0,.2)}
[data-accent="football"] .btn--p{color:#3A2E12}
.btn--g{background:var(--paper);color:var(--ink);border:2px solid var(--ink);box-shadow:0 4px 0 rgba(23,23,26,.16)}
.btn:hover{transform:translateY(-2px)}

/* Adam 2026-08-27：首页各板块的 Enter 按钮要更招手一点。
   做法是**进入视野时轻轻弹一下，然后停**——不是一直动。
   一直跳的按钮在简历网站上像广告，看两次就烦；
   只在滚到它时弹一下，注意力抓到了就收手。
   ⚠️ 只作用于首页板块按钮（.band .btn--p），
   内页的 CTA 和页眉按钮不参与，否则整站都在抖。 */
@keyframes btnNudge{
  0%,100%{transform:translateY(0) scale(1)}
  30%{transform:translateY(-3px) scale(1.035)}
  55%{transform:translateY(0) scale(.995)}
  75%{transform:translateY(-1px) scale(1.012)}
}
.has-rail:not(.has-bare) .band .rv.in .btn--p,
.has-rail:not(.has-bare) .band .btn--p.rv.in{
  animation:btnNudge .72s var(--ease) .45s 2 both}
.btn--p{will-change:transform}
/* hover 时给一个更明确的回应：抬起 + 阴影加深 */
.btn--p:hover{transform:translateY(-3px);box-shadow:0 7px 0 rgba(0,0,0,.22)}
/* 尊重系统的"减少动态效果"设置 —— 不这么做对前庭敏感的人是伤害 */
@media(prefers-reduced-motion:reduce){
  .has-rail:not(.has-bare) .band .rv.in .btn--p,
  .has-rail:not(.has-bare) .band .btn--p.rv.in{animation:none}
}
.tags{display:flex;gap:8px;flex-wrap:wrap;margin-top:22px}
.tag{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:6px 11px;
  border-radius:999px;background:var(--surface);color:var(--muted);border:1px solid var(--line)}
.tag--gold{background:#C8A96A22;color:#8A6F2A;border-color:#C8A96A55}
.tag--acc{background:var(--acc-soft);color:var(--acc-t);border-color:transparent}

/* 页面大标题区 */
.phero{padding-block:clamp(40px,6vw,80px) clamp(36px,5vw,64px)}
/* 首页首屏要在一屏里装完：上留白收紧，各块间距收紧 */
/* 首屏上下留白要「看起来」一样高，所以 padding 不是对称的：
   标题首行上方本来就带一段行距空白，末行文字下方带的更多，
   两边分别补偿之后，肉眼看到的上下距离才相等。 */
.phero--home{padding-block:clamp(24px,2.5vw,34px) clamp(20px,2.1vw,28px)}
/* Adam 2026-08-23：三页页眉的栏格以 contact 那一套为准（原来首页/The Path 是
   1.15fr .85fr gap 44，contact 是 1.05/.95 gap clamp(24,4vw,56)，插画因此对不齐）。
   现在统一走 contact 这一套，插画尺寸也统一到 420。 */
.phero__grid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(24px,4vw,56px);align-items:center}
.phero__one{max-width:66ch}
/* 成长路径首屏那张五人组 */
.jart img{display:block;width:100%;max-width:420px;height:auto;margin-inline:auto;
  filter:drop-shadow(0 24px 30px rgba(23,23,26,.12))}
.phero h1{font-size:clamp(34px,6vw,74px);line-height:1.02;max-width:14ch}
.phero h1:lang(en){max-width:none}
.phero h1 .acc{color:var(--acc-t)}
h1 .acc,h2 .acc{color:var(--acc-t)}

/* HERO（首页） */
.hname{line-height:.84}
.hname .s{display:block;font-size:clamp(26px,3.8vw,46px);color:#B8B8B2}
.hname .b{display:block;font-size:clamp(56px,9.6vw,124px);color:var(--acc)}
.pos{font-family:var(--disp);font-weight:var(--dw);font-size:clamp(20px,2.9vw,32px);line-height:1.24;margin-top:22px;letter-spacing:var(--dls)}
.pos mark{background:var(--acc-soft);color:var(--acc-t);border-radius:8px;padding:0 8px;box-decoration-break:clone;-webkit-box-decoration-break:clone}
/* 首页四个身份词：字用深一档的颜色保证可读，底下压一道块色的马克笔。
   底纹同时是给不靠颜色分辨的人准备的第二重信号，
   也是全站唯一一处真正的金色 #C8A96A 出现的地方。 */
/* Adam 2026-08-27：四个主语现在是链接。
   text-decoration:none 去掉浏览器默认下划线 —— 下面那条 ::after 已经画了色带。
   cursor:pointer 和 hover 时色带加粗，是唯一的"这里能点"的提示。 */
.pos .hw{position:relative;white-space:nowrap;color:var(--hc);
  text-decoration:none;cursor:pointer}
a.hw:hover::after{height:.34em;opacity:.55}
a.hw:focus-visible{outline:2px solid var(--hc);outline-offset:3px;border-radius:3px}

.pos .hw::after{content:'';position:absolute;left:-.05em;right:-.05em;bottom:.02em;height:.22em;
  background:var(--hb);opacity:.28;border-radius:4px}
.mission{font-size:19px;line-height:1.72;color:#3C3C43;max-width:620px;margin-top:26px}
html[lang="en"] .mission{font-size:18.5px;line-height:1.7;max-width:none}

/* 首页两个竖排大按钮：左边是人话，右边是它到底会带你去哪 */
.btnstack{display:flex;flex-direction:column;gap:11px;margin-top:28px;max-width:430px}
.btnw{display:flex;align-items:center;justify-content:space-between;gap:18px;
  text-decoration:none;padding:14px 22px;border-radius:16px;
  background:var(--paper);color:var(--ink);border:2px solid var(--ink);
  box-shadow:0 4px 0 rgba(23,23,26,.14);transition:.2s var(--ease)}
.btnw__t{font-family:var(--disp);font-weight:700;font-size:15.5px;letter-spacing:-.01em}
.btnw__k{font-family:var(--disp);font-size:12px;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:#5E5E64;white-space:nowrap}
.btnw--p{background:var(--ink);color:#fff;border-color:var(--ink);box-shadow:0 4px 0 rgba(0,0,0,.24)}
.btnw--p .btnw__k{color:#B4B4BC}
.btnw:hover{transform:translateY(-2px)}

/* 首页坐标行：你在哪、你是谁的毕业生、怎么找到你。就这三件。
   用正文字体，不用等宽——等宽在这里会读成「开发者页面」 */
.facts{display:flex;flex-wrap:wrap;align-items:center;gap:11px;margin-top:30px;
  font-family:var(--sans);font-size:15px;font-weight:500;letter-spacing:.005em;color:#77777D}
.facts i{font-style:normal;color:var(--line2);font-weight:400}
.facts .f-jhu{color:#3E6E99}
.hmail{display:inline-block;margin-top:10px;font-family:var(--sans);font-size:14.5px;font-weight:600;
  color:var(--ink);text-decoration:none;
  border-bottom:1.5px solid var(--line2);padding-bottom:2px;transition:.2s var(--ease)}
.hmail:hover{border-color:var(--ink)}

/* 中英切换 */
.nav__links>a.lang{font-family:var(--disp);font-size:11px;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--muted);border:1.5px solid var(--line2);
  border-radius:999px;padding:6px 12px;margin-left:6px}
.nav__links>a.lang:hover{border-color:var(--ink);color:var(--ink);background:transparent}

/* 首页插画 + 挂在插画上的 agent 入口 */
.artwrap{position:relative;display:block}
/* Adam 2026-08-23：首页插画的竖向位置对齐 contact。
   contact 的页眉是整屏垂直居中（min-height:100svh + align-items:center），
   首页是从顶上往下排，所以两张插画的竖向差随窗口高度摆动（实测 −13 ~ +104px）。
   要求是「文字不动，只动插画」，所以不能把整个首屏也居中——
   改成只让插画那一栏撑满一屏并在其中居中，文字栏用 align-items:start 钉在顶上。
   ⚠️ 高度里要减掉 2 倍的 section 上内边距：插画栏是从「页眉底 + padTop」开始的，
   减一倍只会把中心推低半个 padTop。64px 这个数要和 contact 那条规则里的
   var(--navh,64px) 保持一致 —— --navh 挂在 .nav 上、传不到 .phero，
   所以 contact 实际上一直用的是兜底值 64。 */
/* ⚠️ 必须带 min-width:901px。栏格在 900px 以下折成单栏（第 485 行），
   这时插画在文字下面，「和 contact 共用一条竖向参考线」这件事就不成立了。
   少了宽度下限，手机上会得到一个 740px 高的空盒子：
   实测首页页眉高 1428px（视口 844），插画和文字之间空出 260px。
   （Adam 2026-08-24 反馈手机自适应很糟，主犯就是这条） */
@media(min-width:901px) and (min-height:640px){
  .phero--home .phero__grid{align-items:start}
  .phero--home .artwrap{
    /* 插画栏要和 contact 的页眉共用同一条参考线：从「页眉底 + contact 的上内边距」
       起算，高度是「一屏 − 页眉 − 两倍 contact 上内边距」。
       ① margin-top 补掉两页 section 上内边距的差（contact 36 / 首页 30，
          在 1024–1440 之间是 5–6px）—— 不补的话矮窗口下会差这 6px。
       ② min-height 只是下限：窗口矮到装不下时盒子被插画自己撑开，
          插画正好落在盒子顶部，也就是 contact 不居中时的那个位置。
       ③ 64px 要和 contact 那条规则里的 var(--navh,64px) 一致 —— --navh 挂在
          .nav 上、传不到 .phero，所以 contact 实际一直用的是兜底值 64。 */
    margin-top:calc(clamp(20px,3vw,40px) - clamp(24px,2.5vw,34px));
    min-height:calc(100svh - 64px - 2 * clamp(20px,3vw,40px));
    display:flex;align-items:center;justify-content:center}
}
.heroart{display:block;width:100%;max-width:420px;height:auto;margin-inline:auto}
/* Adam 2026-08-23：首页主插画以 contact 那张为准 —— 420px、在右栏里居中。
   代价见下面 .agentdock--fb：420 的插画和角落 Q 版在 1240 以下装不下，
   所以 Q 版的出现门槛从 1150 提到 1240。 */
/* 气泡：方形圆角框 + 一个指向商务形象的尖角。首页不再用右下角那个 dock。 */
.artbub{position:absolute;left:88%;top:19%;z-index:3;
  background:#fff;color:var(--ink);border:2px solid var(--ink);border-radius:16px;
  padding:11px 17px;font-family:var(--disp);font-weight:700;font-size:14px;letter-spacing:-.01em;
  box-shadow:0 4px 0 rgba(23,23,26,.16);white-space:nowrap;cursor:pointer;
  transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.artbub::before,.artbub::after{content:'';position:absolute;width:0;height:0;border-style:solid}
.artbub::before{left:18px;bottom:-19px;border-width:19px 15px 0 0;
  border-color:var(--ink) transparent transparent transparent}
.artbub::after{left:21px;bottom:-14px;border-width:15px 11px 0 0;
  border-color:#fff transparent transparent transparent}
.artbub:hover{transform:translateY(-2px);box-shadow:0 6px 0 rgba(23,23,26,.18)}
@media(max-width:980px){ .artbub{left:auto;right:2%;top:16%;font-size:13px;padding:9px 14px} }
@media(max-width:980px){ .heroart{max-width:320px} }

/* 占位 */
/* Q 版形象：一页一个，站在首屏右侧 */
.chibiwrap{display:flex;align-items:flex-end;justify-content:center}
.chibi{display:block;width:100%;max-width:330px;height:auto;
  filter:drop-shadow(0 22px 26px rgba(23,23,26,.13))}
@media (max-width:900px){.chibi{max-width:250px}}
.slot{aspect-ratio:1/1;border-radius:var(--rl);border:2.5px dashed var(--line2);background:var(--surface);
  display:grid;place-items:center;text-align:center;font-family:var(--mono);font-size:10.5px;color:#A4A49E;
  line-height:2;letter-spacing:.06em;padding:16px}
.slot--wide{aspect-ratio:16/9}
.slot--tall{aspect-ratio:3/4}

/* 卡片 / 列表 */
.card{background:var(--paper);border:1.5px solid var(--line);border-radius:var(--rl);padding:24px 26px;
  box-shadow:0 4px 0 rgba(23,23,26,.05)}
.grid2{display:grid;grid-template-columns:.92fr 1.08fr;gap:clamp(26px,4.5vw,54px);align-items:start}
.grid2e{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,3vw,32px)}
.xlist{margin:0;padding:0;list-style:none}
/* 右侧加了照片之后正文列变窄，长课程列表容易在末行只剩几个词。
   text-wrap:balance 让浏览器自己把几行匀开，不支持的浏览器忽略，无副作用。 */
.xlist li{position:relative;padding-left:22px;margin-bottom:11px;color:#3E3E44;font-size:15px;line-height:1.68;
  text-wrap:balance}
.xlist li::before{content:"";position:absolute;left:0;top:9px;width:9px;height:9px;border-radius:3px;background:var(--acc);box-shadow:0 2px 0 rgba(0,0,0,.1)}
.xlist li b{color:var(--ink)}
/* 每一页最重的那一条：统一用金色底。金色 = 全站的「最高荣誉」信号，
   不跟着分页主题色走，这样五个板块之间才认得出是同一个语言。 */
.xlist li.hi{background:#C8A96A1F;border-radius:12px;
  padding:12px 14px 12px 34px;margin:0 -14px 11px;color:var(--ink)}
.xlist li.hi::before{left:14px;top:21px}
.xlist li.todo{color:#9A9A9E}
.xlist li.todo::before{background:var(--line2)}

/* 时间线 */
.tl{position:relative;padding-left:30px}
.tl::before{content:"";position:absolute;left:8px;top:8px;bottom:8px;width:2px;background:var(--line);border-radius:2px}
.tli{position:relative;padding-bottom:clamp(26px,4vw,42px)}
.tli::before{content:"";position:absolute;left:-30px;top:5px;width:18px;height:18px;border-radius:7px;
  background:var(--paper);border:3px solid var(--acc);box-shadow:0 2px 0 rgba(0,0,0,.08)}
.tli.hero::before{background:var(--acc)}
.tli__k{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--acc-t)}
.tli h3{margin:6px 0 4px}
/* 求学页每条的第二行：学位层级。比日期重、比学校名轻，
   和第四行（地点·学位·GPA）刻意拉开——那一行是 13px 常规灰，
   这一行是 13.5px 半粗、字距放开的墨色，两行不会看成同一类信息。 */
.tli__lvl{display:block;margin-top:7px;font-family:var(--disp);font-weight:600;
  font-size:13.5px;letter-spacing:.055em;text-transform:uppercase;color:var(--ink)}
.tli__lvl + h3{margin-top:3px}
.tli__m{font-size:13px;color:var(--muted);margin-bottom:10px}

/* 数字 */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:24px;margin-top:30px}
.stat{font-family:var(--disp);font-weight:800;font-size:clamp(36px,5.2vw,58px);color:var(--acc-t);line-height:.96;letter-spacing:var(--dls)}
.statl{font-family:var(--disp);font-weight:600;font-size:10.5px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);margin-top:9px;display:block}

/* 卡片网格 */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(268px,1fr));gap:18px;margin-top:30px}
/* 栏目内的卡片：用 auto-fill 而不是 auto-fit —— 只有一两张卡时也保持卡片宽度，不会被拉成通栏 */
.cards--sec{grid-template-columns:repeat(auto-fill,minmax(268px,1fr))}
.ccard{background:var(--paper);border:1.5px solid var(--line);border-radius:var(--rl);overflow:hidden;
  box-shadow:0 4px 0 rgba(23,23,26,.05);transition:.25s var(--ease);text-decoration:none;display:block}
.ccard:hover{transform:translateY(-3px);box-shadow:0 7px 0 rgba(23,23,26,.07)}
/* 还没写的栏目：位置先占住，但明确标成草稿，不可点 */
.ccard--draft{border-style:dashed;background:var(--surface);cursor:default}
.ccard--draft:hover{transform:none;box-shadow:none}
.ccard--draft h3{color:#8E8E94}
.ccard--draft p{color:#9C9CA2}
.ccard--draft .more{color:#A8A8AE;font-family:var(--disp);font-weight:700;
  font-size:10px;letter-spacing:.16em}
.ccard__top{height:8px}
.ccard__b{padding:20px 22px 22px}
.ccard h3{font-size:20px;margin-bottom:8px}
.ccard p{font-size:13.5px;color:var(--muted);line-height:1.65;margin:0}
.ccard .k{font-family:var(--disp);font-weight:700;font-size:10px;letter-spacing:.16em;text-transform:uppercase;margin-bottom:10px;display:block}
.ccard .more{font-family:var(--disp);font-weight:700;font-size:12.5px;margin-top:14px;display:inline-block;color:var(--acc-t)}

/* 长文（故事页） */
.prose{max-width:64ch}
.prose p{font-size:16.5px;line-height:1.85;color:#3A3A40;margin:0 0 1.15em}
.prose p b{color:var(--ink)}
.prose h3{margin:2em 0 .6em}
.pull{font-family:var(--disp);font-weight:var(--dw);font-size:clamp(22px,3.2vw,34px);line-height:1.32;
  border-left:4px solid var(--acc);padding-left:22px;margin:clamp(28px,4vw,44px) 0;max-width:26ch;letter-spacing:var(--dls)}
/* 手工断行的引言（Adam 2026-08-06 第十八批「一个短句一行，不要分裂」）：
   26ch 这个 measure 是给**浏览器自动换行**的引言用的——一旦作者自己用 <br> 定了行，
   再压一个 26ch 会让浏览器在作者的行里再断一次，出来的正是他要避免的「分裂」。
   所以手工断行的引言把 max-width 摘掉，行长由文案自己负责。 */
.pull--lines{max-width:none}
.pull cite{display:block;font-family:var(--mono);font-size:10.5px;font-style:normal;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);margin-top:14px}

/* 上一页 / 下一页 */
.pn{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:8px}
.pnl{display:block;text-decoration:none;border:1.5px solid var(--line);border-radius:var(--rl);padding:20px 22px;
  background:var(--paper);box-shadow:0 4px 0 rgba(23,23,26,.05);transition:.22s var(--ease)}
.pnl:hover{transform:translateY(-2px);box-shadow:0 6px 0 rgba(23,23,26,.07)}
.pnl .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.pnl .t{font-family:var(--disp);font-weight:700;font-size:20px;margin-top:7px;display:flex;align-items:center;gap:9px}
.pnl.r{text-align:right}
.pnl.r .t{justify-content:flex-end}

/* 页脚 */
.foot{background:var(--ink);color:var(--paper);padding-block:clamp(48px,6.5vw,80px);border-radius:var(--rl) var(--rl) 0 0;margin-top:0}
.foot h2{color:var(--paper)}
.foot .eyebrow{color:#9B9BA2}
.foot .eyebrow i{background:#9B9BA2}
.fgrid{display:grid;grid-template-columns:1.35fr .65fr;gap:40px}
.fmail{font-family:var(--disp);font-weight:var(--dw);font-size:clamp(19px,2.9vw,34px);color:var(--paper);
  text-decoration:none;border-bottom:2px solid #45454C;letter-spacing:var(--dls);word-break:break-word}
.fmail:hover{border-color:var(--paper)}
.flinks{display:flex;flex-direction:column;gap:2px;margin-top:14px}
.flinks a{font-family:var(--disp);font-weight:600;font-size:13.5px;color:#C0C0C6;text-decoration:none;padding:9px 0;
  border-bottom:1px solid #2B2B31;display:flex;justify-content:space-between;transition:.18s}
.flinks a:hover{color:#fff;padding-left:5px}
.flinks a.soon{color:#7A7A80}
.flinks a.soon span{opacity:.45}
.fine{margin-top:32px;padding-top:16px;border-top:1px solid #2B2B31;display:flex;gap:22px;flex-wrap:wrap}
.fine span{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;color:#79797F}

/* reveal */
.rv{opacity:0;transform:translateY(16px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
.rv.in{opacity:1;transform:none}
html:not(.js) .rv{opacity:1;transform:none}

@media(max-width:980px){
  body{padding-right:0}
  .rail{display:none}
  .dock{right:16px}
  .phero__grid,.grid2,.grid2e,.fgrid,.pn{grid-template-columns:1fr}
  .nav__links>a,.drop__btn{font-size:13px;padding:7px 8px}
  .nav__in{gap:10px;flex-wrap:wrap}
}

/* ============================================================
   成长路径 journey
   ============================================================ */
.journey{position:relative;width:100%;aspect-ratio:970/1546;margin:clamp(34px,5vw,64px) 0 0}
.journey__svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.jtrack{fill:none;stroke:var(--line2);stroke-width:1.8;stroke-linecap:round;stroke-dasharray:1 9;opacity:.85}
.jseg{fill:none;stroke-width:3.2;stroke-linecap:round}
html:not(.js) .jseg{display:none}

.jnode{position:absolute;left:var(--x);top:var(--y);width:0;height:0;
  text-decoration:none;color:inherit;z-index:2}
.jdot{position:absolute;left:-11px;top:-11px;width:22px;height:22px;box-sizing:border-box;
  border-radius:50%;background:var(--paper);border:3px solid var(--line2);
  transition:border-color .45s var(--ease),transform .45s var(--ease),box-shadow .45s var(--ease)}
.jdot::after{content:'';position:absolute;inset:3px;border-radius:50%;
  background:transparent;transition:background .45s var(--ease)}
.jnode.on .jdot{border-color:var(--c);transform:scale(1.15);box-shadow:0 4px 0 var(--c)}
.jnode.on .jdot::after{background:var(--c)}
.jnode:hover .jdot{transform:scale(1.32)}

.jlab{position:absolute;top:0;width:clamp(280px,27.5vw,342px);opacity:.3;
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
/* 整块以圆点为中心垂直居中——条目行数不同也不会跑位 */
.jnode.r .jlab{left:32px;text-align:left;transform:translate(-10px,-50%)}
.jnode.l .jlab{right:32px;text-align:right;transform:translate(10px,-50%)}
.jnode.on .jlab{opacity:1;transform:translate(0,-50%)}
.jy{display:block;font-family:var(--mono);font-size:11px;font-weight:500;
  letter-spacing:.13em;color:var(--muted)}
/* 关键年份加粗：起点 / 荣誉年 / 终点。加粗之外再提一档明度，10.5px 上只靠字重看不出来 */
.jy b{font-weight:800;color:var(--ink)}
.jnode.on .jy b{color:var(--c)}
/* 标题永远一行：nowrap + 收窄字号，节点标签同时加宽到 320px（两侧仍不压线） */
/* 标题两行：两行同字体同字号。第一行（机构/类别）允许折行——USTB 全称 43 个字符，
   在这列宽度里放不下第二行永远 nowrap（都是短词，不会折） */
.jt{display:block;font-family:var(--disp);font-weight:var(--dw);letter-spacing:var(--dls);
  font-size:clamp(15px,1.45vw,19px);line-height:1.22;margin-top:9px;color:var(--ink);
  transition:color .45s var(--ease)}
.jt--b{margin-top:1px;white-space:nowrap}
/* 副行：只有大学那一条用，写全称，比标题小、比条目重 */
/* 条目：一条一行，字体字号全站统一 */
.jli{display:block;font-size:13.5px;line-height:1.5;color:var(--muted);margin-top:4px}
.jnode.on .jt{color:var(--c)}
.jnode.on .jt--b{color:var(--c)}
.js2{display:block;font-size:13px;line-height:1.55;color:var(--muted);margin-top:6px}
.jnode.todo .jdot{border-style:dashed}
.jnode.todo .jt{color:#9A9A9E}
.jnode.todo.on .jt{color:#9A9A9E}

.jend{margin-top:clamp(20px,4vw,44px)}
.chips{display:flex;flex-wrap:wrap;gap:10px}
.chip{display:inline-flex;align-items:center;gap:8px;text-decoration:none;color:var(--ink);
  background:#fff;border:1.5px solid var(--line);border-radius:999px;padding:9px 16px;
  font-size:13.5px;font-weight:500;transition:.2s var(--ease)}
.chip span:last-child{color:var(--muted);font-size:12px}
.chip:hover{border-color:var(--c);transform:translateY(-2px);box-shadow:0 4px 0 var(--c)}

@media(max-width:900px){
  .journey{aspect-ratio:auto;margin-left:14px;padding:6px 0 6px 30px;border-left:2px dashed var(--line2)}
  .journey__svg{display:none}
  .jnode{position:relative;left:auto;top:auto;width:auto;height:auto;display:block;padding:15px 0}
  .jdot{position:absolute;left:-40px;top:20px}
  .jnode.r .jlab,.jnode.l .jlab{position:static;width:auto;left:auto;right:auto;
    top:auto;text-align:left;transform:none;opacity:1}
  .jt{font-size:20px;white-space:normal}
}


/* 经历之间的分隔线：一条经历和它后面挂的案例卡 / 数字条算同一组，横线画在组与组之间 */
/* 经历页里的板块小标题：Sports = 橄榄球 + 篮球，Music = 小号 + Hip-hop，
   School = 学位 + 研究。每个板块自己一条竖线，不被一条通到底的线串成一段。 */
.tlsec{margin:clamp(38px,4.4vw,58px) 0 clamp(16px,2vw,22px);
       padding-top:clamp(30px,3.6vw,44px);border-top:1.5px solid var(--line)}
.tlsec:first-child{margin-top:0;padding-top:0;border-top:0}
.tlsec h2{font-size:clamp(21px,2.3vw,28px);line-height:1.18;margin-top:9px;letter-spacing:-.012em}
[data-tight] .tlsec{margin:var(--g) 0 var(--g);padding-top:var(--g)}
[data-tight] .tlsec:first-child{margin-top:0;padding-top:0}
[data-tight] .tlsec h2{margin-top:7px}
/* 小节只剩眉标、没有大标题时，把它自己的下边距收掉，
   否则会留下大标题原来占的那段空。（Adam 2026-08-06：sports 页） */
[data-tight] .tlsec:not(:has(h2)){margin-bottom:0}

/* ============================================================
   Sports 页：所有眉标 / 日期标 / bullet 点走**绿 → 金**渐变
   （Adam 2026-08-06 第十三批「全篇都改」）。
   只用色板里已有的篮球绿 #2F7D57、橄榄球金 #C8A96A 和金色的深调 #8A6F2A
   （= football 的 --acc-t，tag--gold 的文字色），**没有引入新颜色**。
   这一页是两项运动合并的一页，两个主题色各占一端。

   ⚠️ 文字端收在 #8A6F2A 而不是亮金 #C8A96A：
   亮金落在 --paper #FAFAF8 上对比度只有约 2.1:1，
   11.5px 的全大写小字用它会读不清。#8A6F2A 是 4.6:1，过 AA。
   实色块（bullet 点）不受这条限制，所以那里可以收到亮金。
   第八批那版是「金 → 绿」，现在全站这一页统一成「绿 → 金」一个方向。
   ============================================================ */
body[data-acc="hoops"] .phero .eyebrow,
body[data-acc="hoops"] .band .eyebrow,
body[data-acc="hoops"] .tli__k{
  background:linear-gradient(90deg,#2F7D57 0%,#8A6F2A 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
/* 横线接在文字前面，所以它走渐变的**前半段**（纯绿 → 绿金之间），
   文字接着从那个色继续走到金，整条读下来是连续的一次绿→金。 */
body[data-acc="hoops"] .phero .eyebrow i,
body[data-acc="hoops"] .band .eyebrow i{
  background:linear-gradient(90deg,#2F7D57 0%,#6C7645 100%)}
/* bullet 的小方块：实色块，不是文字，可以收到亮金 */
body[data-acc="hoops"] .band .xlist li::before{
  background:linear-gradient(135deg,#2F7D57 0%,#C8A96A 100%)}
/* 页脚不进来：页脚在 21 个页面上是同一套灰，跟着某一页变色会破坏全站一致 */
/* 没有眉标的小节（school 页第一段）：h2 是首子元素，它的上外边距会穿过
   tlsec 和 wrap 外溢，把整块往下推 7px，于是三个分页的「页头到第一块」
   距离就对不齐了。必须写在 [data-tight] 那条之后，否则被压掉。 */
[data-tight] .tlsec > h2:first-child,.tlsec > h2:first-child{margin-top:0}
.tlgroup + .tlgroup{border-top:1.5px solid var(--line);
  padding-top:clamp(26px,3.4vw,44px);margin-top:clamp(20px,2.6vw,34px)}
/* 没有大标题块的经历页：只留一行 eyebrow */
.phero--slim{padding:clamp(30px,4vw,54px) 0 0}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* 经历页里的案例卡：紧跟在某条经历后面，显眼标题 + 一段陈述 + 能力标签 */
.feat{margin:26px 0 8px;padding:clamp(20px,2.2vw,28px);border-radius:var(--rl);
  background:var(--surface);border:1.5px solid var(--line)}
.feat h3{font-family:var(--disp);font-weight:var(--dw);letter-spacing:var(--dls);
  font-size:clamp(21px,2.5vw,27px);line-height:1.14;margin-top:6px;color:var(--ink)}
/* 案例卡标题的第二行（Adam 2026-08-06 第十一批）：副标题字号 + 灰色。
   和第一行拉开一档字号，读者一眼分得清「标题」和「一句话说明」。 */
.feat h3 .sub{display:block;margin-top:9px;font-size:clamp(14.5px,1.55vw,16.5px);
  line-height:1.34;letter-spacing:0;font-weight:600;color:var(--muted)}
.feat .lead{margin-top:12px;font-size:clamp(15px,1.5vw,16.5px);line-height:1.6;max-width:60ch}
.feat .tags{margin-top:16px}
/* 案例卡左右分栏：左边文字，右边配图——图占掉原来那块留白 */
.feat--split{display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);
  gap:clamp(16px,2vw,26px);align-items:stretch}
.feat__t{display:flex;flex-direction:column;justify-content:center}
.feat__p{position:relative;margin:0;border-radius:calc(var(--rl) - 10px);overflow:hidden;min-height:200px;
  background:var(--paper);border:1.5px dashed var(--line2);display:grid;place-items:center}
.feat__p img{width:100%;height:100%;object-fit:cover;display:block;border:0}
/* 长截图：完整显示不裁切，高度跟着右侧文字走 */
.feat__p img[style*='contain']{object-fit:contain;background:var(--paper);padding:6px}
.feat__p:has(img){border:0}
.feat__p figcaption{position:absolute;left:0;right:0;bottom:0;padding:8px 12px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
  color:#fff;background:linear-gradient(transparent,rgba(23,23,26,.62))}
.feat__p:not(:has(img)) figcaption{position:static;color:var(--muted);background:none}
.feat__slot{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:#A8A8AE;text-align:center;line-height:1.9}
/* 双图版（Adam 2026-08-06 第十一批「两张照片要求尺寸一样大！左右并列排放」）：
   两张 3:4 等宽等高并排。图注挪到图下面——压在图上的渐变条只放得下一行，
   这里每张要三行。整块顶端对齐，不跟着左栏文字拉伸。 */
.feat__p--two{border:0;background:none;overflow:visible;min-height:0;align-self:stretch;
  display:grid;grid-template-columns:1fr 1fr;gap:12px;place-items:stretch}
/* 两张图撑满左栏剩下的高度（和研究卡 .rcard--shots 同一个做法）：
   flex:1 1 auto 在有确定高度的父容器里会让图长过 aspect-ratio 的基准；
   窄屏堆叠后父容器高度变 auto，aspect-ratio 接管，图不会塌成零高。 */
.feat__p--two .fshot{margin:0;min-width:0;display:flex;flex-direction:column}
.feat__p--two .fshot img{width:100%;height:auto;min-height:0;flex:1 1 auto;
  aspect-ratio:3/4;object-fit:cover;display:block;
  border-radius:calc(var(--rl) - 12px);background:var(--paper)}
.feat__p--two .fshot--wait span.feat__slot{display:grid;place-items:center;aspect-ratio:3/4;
  border-radius:calc(var(--rl) - 12px);border:1.5px dashed var(--line2);background:var(--paper)}
/* 图注三行：第一行时间（墨色），后两行说明（灰）——和毕业照那套图注同一个语言 */
.feat__p--two .fshot figcaption{position:static;padding:0;margin-top:9px;background:none;
  font-family:var(--disp);font-weight:600;font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase;line-height:1.72;color:#8A8A90}
.feat__p--two .fshot figcaption span{display:block}
.feat__p--two .fshot figcaption span:first-child{color:var(--ink)}
/* 左右两张图**共用**的一条图注（Adam 2026-08-06 第十六批）：跨两列排在图下面。
   行距和单图图注同一套，只是不再各写各的。 */
.feat__p--two{grid-template-rows:minmax(0,1fr) auto;column-gap:12px;row-gap:9px}
.feat__p--two .fcap{grid-column:1/-1;font-family:var(--disp);font-weight:600;font-size:10.5px;
  letter-spacing:.11em;text-transform:uppercase;line-height:1.72;color:#8A8A90}
.feat__p--two .fcap span{display:block}
.feat__p--two .fcap span:first-child{color:var(--ink)}
/* bullet + 并排宽图（Adam 2026-08-06 第十五批「加宽这个位置，然后在 blank 处插入图片」）。
   照片的左右边缘和上下两张故事卡的图列**完全对齐**：
   .feat 的内边距 clamp(18px,2vw,24px) 再加 1.5px 边框 = 图列的右内缩，
   图列宽 = (卡内宽 - 列间距) x .44（.feat--split 是 1.12fr / .88fr）。
   这两个值在这里原样复算一遍，所以三张图的左右边缘落在同两条竖线上。 */
/* Adam 2026-08-20：这一排的上下留白太大 —— bullet 只有三行（114px），
   图却有 233px，bullet 垂直居中之后上下各空出 60px。
   把图列从 .44 收到 .34（图高 233 → 180，上下各余 33px），
   并把这一排的上下外边距从 var(--g) 收到 g 的 .6 倍。
   **右边缘仍和上下两张故事卡的图列对齐**（padding-right 没动），
   只是左边缘往里收 —— 保住一条竖线，牺牲另一条。 */
.xrow{--xp:calc(clamp(18px,2vw,24px) + 1.5px);--xg:clamp(16px,2vw,26px);
  display:grid;grid-template-columns:minmax(0,1fr) calc((100% - var(--xp) - var(--xg)) * .34);
  gap:var(--xg);padding-right:var(--xp);align-items:center;
  margin-top:calc(var(--g) * .6);margin-bottom:calc(var(--g) * -.4)}
.xshot{margin:0;min-width:0}
.xshot img{width:100%;height:auto;object-fit:cover;display:block;
  border-radius:calc(var(--rl) - 12px);background:var(--paper)}
.xshot--wait .xslot{display:grid;place-items:center;border-radius:calc(var(--rl) - 12px);
  border:1.5px dashed var(--line2);background:var(--paper)}
.xshot figcaption{display:block;margin-top:9px;font-family:var(--disp);font-weight:600;
  font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;line-height:1.72;color:#8A8A90}
.xshot figcaption span{display:block}
.xshot figcaption span:first-child{color:var(--ink)}
/* 窄屏堆叠：图挪到 bullet 下面，占满整宽 */
@media(max-width:820px){.xrow{grid-template-columns:1fr;padding-right:0;gap:14px}}
@media(max-width:820px){.feat--split{grid-template-columns:1fr}.feat__p{min-height:190px}}
/* 条目后面的数字条：比页首那排小一号，别抢主标题 */
.stats--in{margin:22px 0 8px;padding:18px 0 2px;border-top:1.5px solid var(--line)}
.stats--in .stat{font-size:clamp(26px,3.4vw,38px)}

/* ============================================================
   图位（照片 / Q 版形象），先留白
   ============================================================ */
.shots{display:grid;gap:12px;margin-top:22px;align-items:start}
.shots--4{grid-template-columns:repeat(4,1fr)}
.shots--2{grid-template-columns:repeat(2,1fr)}
.shots--tall .shotf img,.shots--tall .shot{aspect-ratio:3/4}
.shots--sq .shotf img,.shots--sq .shot{aspect-ratio:1/1}
/* 透明底的拼图：不裁、不加底色、不圆角 */
.shotf.shotf--free img{aspect-ratio:4/3;object-fit:contain;background:none;border-radius:0}
.shot{aspect-ratio:4/3;border-radius:14px;border:2px dashed var(--line2);background:var(--surface);
  display:flex;align-items:center;justify-content:center;text-align:center;padding:10px;
  font-family:var(--disp);font-weight:600;font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase;color:#A6A6AC;line-height:1.6}
/* 真实照片：不要虚线框，图片本身就是内容 */
.shotf{margin:0}
.shotf img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:14px;display:block;
  background:var(--surface)}
.shotf figcaption{display:block;margin-top:9px;font-family:var(--disp);font-weight:600;
  font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:#8A8A90;line-height:1.55}
@media(max-width:900px){ .shots--4{grid-template-columns:repeat(2,1fr)} }

/* 整排共用一条图注（Adam 2026-08-24，小号那排四张）。
   字号、字重、字距、颜色全部抄 .shotf figcaption，不新造一套观感。
   .shots 自己带 margin-top:22px，所以外层不再加，避免和上面的 bullet 拉开两次。 */
.shotrow{margin-top:0}
.shotrow .shots{margin-top:22px}
.shotrow__cap{margin:9px 0 0;font-family:var(--disp);font-weight:600;
  font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:#8A8A90;line-height:1.55}

/* 五颗星代替数字：盒子高度必须和 .stat 一样，下面的小标签才会对齐在同一行 */
.stars{display:flex;align-items:center;height:calc(clamp(36px,5.2vw,58px) * .96);
  font-size:clamp(28px,4vw,42px);color:var(--gold);letter-spacing:.08em;line-height:1;
  -webkit-text-stroke:1.2px #276848;paint-order:stroke fill}
.nb{white-space:nowrap}

/* 页脚左侧的白色联系卡 */
.fcard{background:#fff;color:var(--ink);border-radius:var(--rl);padding:26px 28px;max-width:450px}
.fcard h3{font-size:clamp(20px,2.4vw,26px);line-height:1.2;margin:0 0 20px}
.fcard dl{margin:0;display:grid;grid-template-columns:auto 1fr;gap:12px 20px;align-items:baseline}
.fcard dt{font-family:var(--disp);font-weight:700;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:#8A8A90}
.fcard dd{margin:0;font-size:15px;line-height:1.5}
.fcard a{color:var(--ink);text-decoration:none;border-bottom:1.5px solid var(--line2)}
.fcard a:hover{border-color:var(--ink)}
.frelo{margin-top:28px;font-size:clamp(16px,1.8vw,19px);line-height:1.65;color:#C7C7CE;max-width:44ch}
.frelo b{color:#fff;font-weight:400}

/* ============================================================
   间距统一（Adam 2026-08-05）：标了 data-tight 的页面，
   页内所有「块与块之间」的留白统一成一个值 --g，不再各处一个数。
   段内的行距、标题到副标题这种「块内部」的间距不动——那是层次，不是留白。
   ============================================================ */
[data-tight]{--g:clamp(24px,3vw,34px)}
[data-tight] .band{padding-block:var(--g)}
[data-tight] .phero--slim{padding:var(--g) 0}
/* Adam 2026-08-06：分页眉标和第一条之间的留白减半，并取消中间那条分隔横线。
   目的是让第一段经历尽量一屏看完。两处各减一半，合起来正好是「缩小一倍」。 */
[data-tight] .phero--slim{padding-bottom:calc(var(--g) / 2)}
[data-tight] .phero--slim + .band{border-top:0;padding-top:calc(var(--g) / 2)}
/* Adam 2026-08-06「全网页统一」：所有**页眉型** phero 都是同一条缝——
   没有横线、上下各 17px。首页的 .phero--home 是落地页主视觉不是页眉，排除在外。 */
.phero:not(.phero--home){padding-bottom:17px}
.phero:not(.phero--home) + .band{border-top:0;padding-top:17px}
/* band 里第一块自带的上外边距会把这条缝撑大（music 的数字条、says 的卡片墙），一律清掉 */
.band .wrap > :first-child{margin-top:0}
/* 首页主视觉下面那条横线也去掉（Adam：全网页统一取消间隔横线）。
   首页的间距不动——.phero--home 是落地页主视觉，不是页眉。 */
.phero--home + .band{border-top:0}
[data-tight] .phero--slim .eyebrow{margin-bottom:0}
[data-tight] .tl{margin-top:0 !important}
[data-tight] .tli{padding-bottom:0}
[data-tight] .xlist{margin-bottom:0}
[data-tight] .xlist li{margin-bottom:7px}
[data-tight] .xlist li:last-child{margin-bottom:0}
[data-tight] .feat{padding:clamp(18px,2vw,24px)}
[data-tight] .feat__p{min-height:186px}
[data-tight] .feat{margin:var(--g) 0 0}
[data-tight] .stats--in{margin:var(--g) 0 0;padding:0;border-top:0}
[data-tight] .tlgroup + .tlgroup{margin-top:var(--g);padding-top:var(--g)}
[data-tight] .grid2e{margin-top:var(--g) !important}

/* 研究项目三条：并排三张实底卡（Adam 2026-08-06 指定的版式）。
   底色用 var(--acc-t)（主题色自己的深色调，本页正文里已经在用），
   白字在 #3E6E99 上对比度约 5.6:1，过 AA；不引入色板外的新颜色。 */
.rcards{display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(14px,1.7vw,20px);margin-top:var(--g)}
/* 卡头：大数字 + 一行说明 */
.rcard__hero{display:flex;align-items:baseline;gap:10px;margin-bottom:12px}
/* 卡一里的第二个数字块（30+ Decks built）：和第一个同款，上面留一道分隔 */
.rcard__hero--2{margin:0;padding-top:16px;border-top:1px solid var(--line)}
/* 卡二只放图：两张竖着排，各自撑开、居中 */
/* Adam 2026-08-06：**右栏以左栏为准**。卡二只放图，图必须收缩去适应
   卡一的自然高度，而不是把整行撑高——所以 min-height 归零、flex 基准 0，
   两张图按比例分掉卡里剩下的高度。contain 保证不裁切。 */
.rcard--shots{gap:12px;justify-content:center}
.rcard--shots .rcard__shot{margin-top:0;flex:1 1 0;min-height:0}
.rcard__hero b{font-family:var(--disp);font-weight:800;font-size:34px;line-height:1;color:var(--acc-t)}
.rcard__hero span{font-family:var(--disp);font-weight:600;font-size:14px;color:var(--ink)}
/* 卡一里的三条研究 */
.rlist{list-style:none;margin:0 0 14px;padding:0}
.rlist li{position:relative;padding-left:16px;margin-bottom:10px;color:#3E3E44;
  font-size:14px;line-height:1.55}
.rlist li::before{content:"";position:absolute;left:0;top:8px;width:6px;height:6px;
  border-radius:2px;background:var(--acc)}
.rlist em{display:block;font-style:normal;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.09em;text-transform:uppercase;color:var(--muted);margin-top:3px}
/* 卡里的图槽：文件在就上图，不在就虚线占位 */
.rcard__shot{width:100%;border-radius:10px;display:block;margin-top:14px;
  flex:1 1 auto;min-height:112px;box-sizing:border-box}
/* 透明 PNG：contain 完整显示，不加底色也不裁切 */
img.rcard__shot{object-fit:contain;background:none}
.rcard__shot--wait{flex:0 0 auto;border:2px dashed var(--line2);background:var(--surface);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  text-align:center;padding:8px;font-family:var(--mono);font-size:9.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted)}
.rcard__shot--wait span{opacity:.75;font-size:8px;letter-spacing:.03em;text-transform:none}
/* 2026-08-06：原来这里用 margin-left:-30px 把卡片顶出时间轴缩进，
   结果卡片比上面的正文往左溢出 30px。Adam 指出来了，已撤销——
   卡片和正文左边缘对齐。 */
/* Adam 2026-08-06：取消蓝底，和下面本科那张 essays 卡统一成浅色卡。 */
.rcard{background:var(--paper);border:1.5px solid var(--line);color:var(--ink);
  border-radius:var(--rl);padding:clamp(18px,1.9vw,24px);display:flex;flex-direction:column}
.rcard__k{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--acc-t)}
/* 卡片上半部：左边日期/标题/副题，右边给论文标题页留的 A4 竖版槽位。
   Adam 把 paper-1..3.jpg 放进 assets/img/ 就自动换上，没放就是虚线占位。 */
.rcard__t{display:grid;grid-template-columns:1fr 84px;gap:12px;align-items:start}
.rcard__pg{width:84px;aspect-ratio:1/1.414;border-radius:6px;display:block;box-sizing:border-box}
img.rcard__pg{object-fit:cover;background:#ffffff1a}
.rcard__pg--wait{border:1.5px dashed var(--line2);background:var(--surface);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  text-align:center;padding:6px;line-height:1.35;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted)}
.rcard__fn{opacity:.75;font-size:7.5px;letter-spacing:.03em;text-transform:none}
.rcard h3{margin:9px 0 3px;font-size:18px;line-height:1.24;color:var(--ink)}
.rcard__m{font-size:12.5px;color:var(--muted);margin-bottom:10px}
.rcard p{margin:0;font-size:13.5px;line-height:1.62;color:#3E3E44}
@media(max-width:900px){.rcards{grid-template-columns:1fr}}

/* 每条学历右侧的毕业照（Adam 2026-08-06）。左正文右图，窄屏堆叠。
   四张 entry 侧的照片统一 4:3；essays 卡里那张是竖版 3:4，属于另一个位。 */
/* Adam 2026-08-06：五张毕业照**同宽**，而且**左边缘落在同一条竖线上**。
   essays 卡里那张被卡片内边距（26px + 1.5px 边框）往里推，所以 entry 侧的照片
   也让出同样的量（--gradinset），两边右边缘一致、同宽 → 左边缘自然对齐。
   高中/初中/小学这一轮按要求整体放大（23% → 27%）。 */
/* 注意：--gradw 必须是**绝对长度**。用百分比会在两个容器里按不同基准解析
   （.tli__g 按 tli 宽、.esy__g 按卡片内宽、figure 按所在网格列宽），
   三处算出三个值，照片就对不齐了——这一版就是踩了这个才改成 vw 的。 */
:root{--gradw:clamp(190px,20vw,268px);--gradinset:27.5px}
.tli__g{display:grid;
  grid-template-columns:minmax(0,1fr) calc(var(--gradw) + var(--gradinset));
  gap:clamp(18px,2.4vw,30px);align-items:start}
/* 照片顶部下移到和「MASTER'S DEGREE」那一行持平（Adam 要求），
   偏移量 = 日期行行高 + 层级行的上边距。 */
.tli__g > .tli__pic{width:var(--gradw);margin-right:var(--gradinset);margin-top:34px}
.tli__pic{margin:0}
.tli__pic img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:14px;display:block;
  box-shadow:0 10px 22px rgba(23,23,26,.10)}
/* 图注两行：第一行时间+场合（墨色、稍重），第二行合影对象（灰） */
.tli__pic figcaption{display:block;margin-top:10px;font-family:var(--disp);
  font-size:11.5px;line-height:1.42;letter-spacing:.01em}
.tli__pic figcaption b{display:block;font-weight:700;color:var(--ink)}
.tli__pic figcaption span{display:block;font-weight:500;color:var(--muted);margin-top:2px}
.slotp{width:100%;aspect-ratio:4/3;border-radius:14px;border:2.5px dashed var(--line2);
  background:var(--surface);display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:6px;text-align:center;padding:10px;
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted)}
.slotp span{opacity:.7;font-size:9px;letter-spacing:.04em;text-transform:none}

@media(max-width:860px){.tli__g{grid-template-columns:1fr}}

/* 八篇长文那一块：左边文字 + 右边图。Adam 2026-08-06 要求提到本科那一条后面。 */
.esy{margin-top:var(--g)}
.esy__g{display:grid;grid-template-columns:minmax(0,1fr) var(--gradw);
  gap:clamp(18px,2.6vw,32px);align-items:center}
.esy__g > img{width:100%;height:auto;display:block;border-radius:12px}
.esy__g > .tli__pic{margin:0}
.tli__pic--tall img,.tli__pic--tall .slotp{aspect-ratio:3/4}
.esy__n{display:flex;gap:clamp(18px,2.6vw,34px);margin:14px 0 4px;flex-wrap:wrap}
.esy__n div{display:flex;flex-direction:column}
.esy__n b{font-family:var(--disp);font-weight:800;font-size:26px;line-height:1;color:var(--acc-t)}
.esy__n span{font-family:var(--mono);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);margin-top:5px}
@media(max-width:820px){ .esy__g{grid-template-columns:1fr} }

/* 九个 Q 版人物：脚（或车轮）踩在每段线的中点上，跟着曲线往前跑。
   --k = 这张图的 宽/统一身高。CSS 只设宽度，于是七个人的屏上高度
   恒等于 --figH（**所有人物完全一样大**），两张开车的按「着墨面积等于
   人物平均着墨面积」配平，整体看上去和人差不多大。
   translate(-50%,-100%) = 水平对准中点、**底边**对准中点；
   再往上抬 --figgap（线宽的一半 + 一点点缝），就是 Adam 要的「贴着线留微小 blank」。
   注意：九张图都是按最终朝向画好的（车标、队名、球衣号都在图里），
   **不许用 scaleX(-1) 翻转**，一翻就全是镜像字。 */
.journey{--figH:15.5%;--figgap:4px}
.jfig{position:absolute;left:var(--x);top:var(--y);
  width:calc(var(--figH) * var(--k));height:auto;
  transform:translate(-50%,calc(-100% - var(--figgap)));
  pointer-events:none;user-select:none;
  filter:drop-shadow(0 7px 11px rgba(23,23,26,.13))}
/* 有 JS 时先藏起来，由 site.js 跟着线段的绘制进度淡入；没 JS 就直接显示 */
html.js .jfig{opacity:0}
html.js .jfig{transition:opacity .18s linear}
@media(max-width:900px){.jfig{display:none}}
@media(prefers-reduced-motion:reduce){html.js .jfig{opacity:1 !important}}

/* 孤字的根治办法：让浏览器自己避免「最后一行只剩几个字」。
   Chrome / Safari 支持 text-wrap:pretty，不支持的浏览器忽略这一行，不会有副作用。 */
p,.lead,.xlist li,.feat p,.tli__m,.js2,.jli{text-wrap:pretty}
h1,h2,h3,.jt{text-wrap:balance}
/* Adam 2026-08-24：抖音段那条高亮 bullet 比别的窄（它有内边距和底色），
   pretty 压不住 —— 末行只剩 16%（101/627），就是残行。
   这一条改用 balance 把几行匀开。选择器要比上面那条 (0,2,0) 更具体。 */
.xlist li.hi{text-wrap:balance}

/* 案例卡：图片在左、文字在右 */
.feat--flip{grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr)}
.feat--flip .feat__t{order:2}
.feat--flip .feat__p{order:1}
/* 还没拿到的现场照：虚线占位，写着文件名 */
.shotf--wait{display:grid;place-items:center;background:var(--paper);
  border:1.5px dashed var(--line2);border-radius:var(--rl);aspect-ratio:4/3}
.shotf--wait figcaption{margin-top:0;padding:0 10px 10px}
@media(max-width:820px){.feat--flip{grid-template-columns:1fr}
  .feat--flip .feat__t{order:2}.feat--flip .feat__p{order:1}}
.shots--3{grid-template-columns:repeat(3,1fr)}

/* ============================================================
   站内检索浮层（2026-08-06 上线小样的「agent」）
   不是生成式的：只在站内索引里找，命中什么就给什么，并给出出处页面。
   ============================================================ */
.ask[hidden]{display:none}
.ask{position:fixed;inset:0;z-index:200;display:grid;place-items:start center;padding:12vh 20px 20px}
.ask__bg{position:absolute;inset:0;background:rgba(23,23,26,.42);backdrop-filter:blur(3px)}
.ask__box{position:relative;width:min(720px,100%);background:var(--paper);
  border:1.5px solid var(--line);border-radius:var(--rl);box-shadow:0 24px 60px rgba(23,23,26,.22);
  overflow:hidden;animation:askin .18s ease}
@keyframes askin{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.ask__top{display:flex;align-items:center;gap:12px;padding:16px 16px 14px;border-bottom:1.5px solid var(--line)}
.ask__top .brand__m{flex:0 0 auto}
.ask__top input{flex:1;min-width:0;border:0;background:none;outline:none;
  font-family:var(--disp);font-size:17px;font-weight:600;color:var(--ink);letter-spacing:.005em}
.ask__top input::placeholder{color:#A8A8AE;font-weight:500}
.ask__x{border:0;background:none;font-size:26px;line-height:1;color:#9A9A9E;cursor:pointer;padding:0 4px}
.ask__x:hover{color:var(--ink)}
.ask__res{max-height:min(52vh,520px);overflow:auto;padding:6px}
.ask__hint{margin:22px 16px;color:var(--muted);font-size:14.5px;line-height:1.7}
.ask__i{display:block;padding:13px 14px;border-radius:12px;text-decoration:none;color:inherit}
.ask__i:hover,.ask__i:focus-visible{background:var(--surface);outline:none}
.ask__i .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:#8A8A90;margin-bottom:5px}
.ask__i h4{font-family:var(--disp);font-weight:700;font-size:15px;margin:0 0 4px;color:var(--ink)}
.ask__i p{margin:0;font-size:13.5px;line-height:1.62;color:#4A4A52}
.ask__i mark{background:#C8A96A38;color:inherit;border-radius:3px;padding:0 2px}
.ask__foot{padding:11px 16px;border-top:1.5px solid var(--line);background:var(--surface);
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:#9A9A9E}
/* contact 页：卡片顶部一条主题色，替掉原来纯黑白 */
.card--top{border-top:4px solid var(--top,var(--acc))}
button.chip{cursor:pointer;font:inherit}

/* Chrome 给 type=search 自带一个清除按钮，和我们的关闭按钮并排出现，像两个 × */
.ask__top input::-webkit-search-cancel-button,
.ask__top input::-webkit-search-decoration{-webkit-appearance:none;appearance:none}

/* 深链接落点：顶部导航是吸顶的，锚点要往下让出导航高度，
   否则跳过去之后目标条目正好被导航盖住。 */
.tlgroup,.tlsec,.band[id],section[id]{scroll-margin-top:96px}
html{scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* 并排两张图必须等高（Adam 2026-08-06）：
   图注行数不一样时，原来每个 figure 各自按自己的图注高度去挤图，
   两张图就不一样高了。subgrid 让两个 figure 共用同一组行——
   图全在第一行（1fr，等高），图注全在第二行（auto，取最高的那条）。 */
.feat__p--two .fshot{display:grid;grid-template-rows:subgrid;grid-row:span 2;row-gap:9px}
.feat__p--two .fshot img{flex:none;height:100%;min-height:0}
.feat__p--two .fshot figcaption{margin-top:0}
/* 不支持 subgrid 的浏览器：退回固定 3:4，两张图靠列宽相同保证等大 */
@supports not (grid-template-rows: subgrid){
  .feat__p--two .fshot{display:flex;flex-direction:column}
  .feat__p--two .fshot img{flex:none;height:auto;aspect-ratio:3/4}
  .feat__p--two .fshot figcaption{margin-top:9px}
}

/* contact 页的页眉：左文右图（Adam 2026-08-06「把首页插画放到 contact 标题右侧」）。
   首页的 .phero__grid 是给巨大姓名排版用的，比例和纵向留白都不一样，
   这里单独收一版：两列更接近 1:1，图小一号，顶部留白按内页走。 */
/* Adam 2026-08-23（改了方向）：以 contact 这张插画为全站基准 ——
   420px、在右栏里居中、栏格 1.05fr/.95fr gap clamp(24,4vw,56)。
   那套值现在写进了通用的 .phero__grid / .heroart / .jart img，
   所以这里不需要再单独覆盖，只留 contact 自己的排布方式。 */
.phero__grid--c{align-items:center}
.artwrap--c{display:flex;justify-content:center;align-items:flex-end}
@media(max-width:900px){
  .phero__grid--c{grid-template-columns:1fr}
  .artwrap--c{order:2;margin-top:8px}
  .artwrap--c .heroart{max-width:300px}
}
/* 只留一行版权的页脚（contact 页用）：上面已经有完整联系方式，不再重复一遍 */
.foot--slim{padding:clamp(26px,3vw,38px) 0}
.foot--slim .fine{border-top:0;margin-top:0;padding-top:0}

/* ============================================================
   contact 页的「全色板渐变」（Adam 2026-08-06）：
   把站里五个主题色按人生顺序串成一条 —— 小号紫 → 篮球绿 → 橄榄球金 →
   学术浅蓝 → 职业藏蓝。**没有引入色板外的新颜色。**
   文字端用的是每个色的深调（#6B4E9E / #276848 / #8A6F2A / #3E6E99 / #3A4E78），
   亮金 #C8A96A 落在纸色上只有 2.1:1，小字读不清；实色条不受这条限制。
   ============================================================ */
.eyebrow--rainbow{
  background:linear-gradient(90deg,#6B4E9E 0%,#276848 30%,#8A6F2A 55%,#3E6E99 78%,#3A4E78 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.eyebrow--rainbow i{background:linear-gradient(90deg,#6B4E9E 0%,#4F5B84 100%)}
/* 两张卡的顶边：实色条，可以用亮色 */
.card--rainbow{position:relative;overflow:hidden}
.card--rainbow::before{content:"";position:absolute;left:0;right:0;top:0;height:4px;
  background:linear-gradient(90deg,#6B4E9E 0%,#2F7D57 30%,#C8A96A 55%,#6E9CC4 78%,#3A4E78 100%)}
/* 故事页配图：有图才出（没有图整块不渲染，见 _storypic） */
.storypic{margin:0}
.storypic img{width:100%;height:auto;display:block;border-radius:var(--rl);background:var(--surface)}

/* ============================================================
   手机端（Adam 2026-08-09）
   ------------------------------------------------------------
   实测 390px 下的三个硬伤：
   ① 导航一行排不下，Resume 按钮被切在屏幕外（.nav__links 右边缘 419 > 390）
   ② 右下角 agent 按钮 + 气泡整体溢出到 406
   ③ 一批 9 / 9.5px 的等宽小字，在手机上读不动
   ============================================================ */

/* ---------- ① 汉堡菜单 ---------- */
.navtog{display:none;margin-left:auto;width:44px;height:44px;border:0;background:none;
  padding:11px 9px;cursor:pointer;border-radius:12px}
.navtog:hover{background:var(--surface)}
.navtog span{display:block;height:2px;border-radius:2px;background:var(--ink);
  transition:transform .22s var(--ease),opacity .18s}
.navtog span+span{margin-top:5px}
.navtog[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.navtog[aria-expanded="true"] span:nth-child(2){opacity:0}
.navtog[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

@media(max-width:760px){
  .nav__in{gap:8px;flex-wrap:nowrap;padding:10px 18px}
  .navtog{display:block}
  /* 链接区变成从导航条下面滑出的整屏面板 */
  .nav__links{position:fixed;left:0;right:0;top:var(--navh,58px);
    margin-left:0;display:block;background:var(--paper);
    border-bottom:1.5px solid var(--line);box-shadow:0 18px 40px rgba(23,23,26,.13);
    padding:8px 18px 20px;max-height:calc(100dvh - var(--navh,58px));overflow:auto;
    opacity:0;visibility:hidden;transform:translateY(-8px);
    transition:opacity .2s,transform .22s var(--ease),visibility .2s}
  .nav.open .nav__links{opacity:1;visibility:visible;transform:none}
  /* 触控目标一律 ≥44px */
  .nav__links>a,.drop__btn{display:flex;align-items:center;width:100%;
    min-height:46px;font-size:16px;padding:0 10px;border-radius:12px}
  .nav__links>a.on::after,.drop.on .drop__btn::after{margin-left:8px}
  .drop{position:static}
  /* 手机上没有 hover：下拉直接展开成缩进的子项，不再是浮层 */
  .drop__menu{position:static;opacity:1;visibility:visible;transform:none;
    box-shadow:none;border:0;padding:0 0 6px 12px;min-width:0;background:none}
  .drop__menu a{min-height:42px;font-size:14.5px;padding:0 10px}
  .nav__links>a.cta{justify-content:center;margin-top:10px;min-height:50px;font-size:15px}
  .nav__links>a.lang{justify-content:center;margin-top:8px}
}

/* ---------- ② 右下角 agent ---------- */
@media(max-width:760px){
  /* 气泡在手机上占掉半个屏，收起来；按钮缩小并保证 44px 触控 */
  .dock__bub,.agentdock__t{display:none}
  .dock{right:12px;bottom:12px;gap:0}
  .dock__av{width:52px;height:52px;border-radius:16px}
  .agentdock{right:12px;bottom:12px;min-height:46px;font-size:12px;padding:9px 13px}
  .chibi{max-width:150px}
}

/* ---------- ③ 小字下限 ---------- */
@media(max-width:760px){
  /* 9 / 9.5px 在手机上读不动，统一抬到 11px；字距同时收一点，
     否则抬大之后一行放不下 */
  .eyebrow,.tli__k,.statl,.shotf figcaption,.fine,.pnl .k,
  .feat__p--two .fshot figcaption,.feat__p--two .fcap,.xshot figcaption,
  .ccard .k,.ask__i .k,.ask__foot{font-size:11px;letter-spacing:.1em}
  .tag,.chip{font-size:11.5px}
  .lead,.prose p,.xlist li{font-size:15.5px}
  /* 宽按钮：手机上标签和副标题竖排，别挤成四行 */
  .btnw{flex-direction:column;align-items:flex-start;gap:6px;min-height:0;padding:16px 18px}
  .btnw__t{font-size:17px}
}

/* ---------- ④ 检索浮层在手机上贴顶铺满 ---------- */
@media(max-width:760px){
  .ask{padding:0;place-items:stretch}
  .ask__box{width:100%;height:100dvh;border-radius:0;border:0;display:flex;flex-direction:column}
  .ask__res{flex:1;max-height:none}
  .ask__top input{font-size:16px}   /* <16px 会让 iOS 自动放大整页 */
}

/* ---------- ⑤ 手机端补丁（实测查出来的四处） ---------- */
@media(max-width:760px){
  /* 首页带 .has-rail 时 CTA 有 translateX(50%)，在竖排面板里会把按钮推出屏幕右边
     （实测 203..557 vs 兄弟节点 18..372）。手机上没有右侧 rail，整条撤掉。 */
  .has-rail .nav__links>a.cta,
  .has-rail .nav__links>a.cta:hover{transform:none}
  .nav__links>a.cta{margin-left:0;width:100%}
  /* 下拉的小三角在手机上没用（菜单本来就是展开的），而且它是 9px */
  .drop__btn span{display:none}
  /* 页脚细则和图注：11px 下限要落到真正带字的元素上 */
  /* 图注散在好几个类里（.feat__p / .tli__pic / .shotf / .xshot …），
     手机端一律抬到 11px，用 figcaption 兜底最省事 */
  .fine,.fine span,figcaption,.shotf figcaption,.tli__pic figcaption,
  .feat__p figcaption{font-size:11px;letter-spacing:.1em}
  /* 品牌标识的触控高度 */
  .brand{min-height:44px}
}

/* ---------- ⑥ 极窄屏（320px，iPhone SE 一代 / 分屏）---------- */
/* 实测 320px 下整页被撑到 375：源头是页脚名片里的邮箱
   AdamZhangZiwen@outlook.com —— 一个不可断的长串，把 dl 的第二列顶到 203px，
   加上 .wrap 固定的 36px 内边距就超了。三处一起改： */
@media(max-width:400px){
  .wrap{padding-inline:20px}
  .fcard{padding:22px 20px}
  .fcard dl{grid-template-columns:1fr;gap:2px 0}
  .fcard dt{margin-top:10px}
  .fcard dd,.fcard dd a,.fine span,.flinks a{overflow-wrap:anywhere}
  .fine{flex-wrap:wrap;gap:6px 14px}
}

/* 触屏上把联系方式的点击区撑到 41px（Adam 2026-08-24）。
   电话 / LinkedIn / 邮箱这三个链接本身只有 17px 高 —— 手机上很难点中，
   而它们恰恰是这个站最重要的点击目标。
   用伪元素撑热区而不是加 padding：**排版一个像素不动**，下划线位置也不变。
   相邻两条之间永远隔着一个 dt 标签（不可点），所以热区不会互相打架。 */
@media(hover:none){
  .fcard a{position:relative}
  .fcard a::after{content:"";position:absolute;left:0;right:0;top:-12px;bottom:-12px}
  /* contact 页正文里的四条联系方式、More of Me 里的三条外链，
     都是 .xlist 里的行内链接，同样只有 17px 高。同一套办法。
     ⚠️ 只给 .xlist 里的链接，不要给所有 a —— 卡片、按钮本来就够大，
     再撑热区会和相邻元素抢点击。 */
  .xlist a{position:relative}
  .xlist a::after{content:"";position:absolute;left:0;right:0;top:-12px;bottom:-12px}
}

/* .nb 是防孤字用的 white-space:nowrap。在 320px 这种极窄屏上，
   一个不许断的长短语反而会把整页撑出横向滚动（实测 story-sideline +49px）。
   孤字是阅读宽度下的问题，横向滚动是任何宽度下的问题——窄屏优先保后者。
   orphan.js 检查的九个宽度都在 940 以上，不受这条影响。 */
@media(max-width:430px){.nb{white-space:normal}}

/* ============================================================
   视频卡（Adam 2026-08-09）：首页 Content Creator 那一排。
   竖屏 9:16 —— 抖音是竖视频，用 4:3 的横框去装会两边留黑边。
   封面没给的时候出同尺寸虚线占位，**格子的位置和大小不变**，
   一张一张填不会让这一排塌掉。
   ============================================================ */
.vrow{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(12px,1.6vw,18px);
  margin-top:clamp(22px,3vw,34px)}
.vcard{display:block;text-decoration:none;color:inherit;min-width:0}
.vcard__f{position:relative;display:block;border-radius:14px;overflow:hidden;
  background:var(--surface);aspect-ratio:9/16}
.vcard img{width:100%;height:100%;object-fit:cover;display:block}
/* 内嵌视频（Adam 2026-08-23）：和封面图同一套裁切，格子尺寸不因视频比例变化。
   原片是 9:16 竖屏，卡片本身也是竖的，所以 cover 基本不裁到东西。
   ⚠️ 视频卡不要再叠我们自己的播放角标 —— 浏览器原生控件已经有一个居中的播放钮，
   两个叠在一起会打架。 */
.vcard--vid video{width:100%;height:100%;object-fit:cover;display:block;background:#17171A}
.vcard--vid .vcard__p{display:none}
.vcard--wait .vcard__f{border:1.5px dashed var(--line2);background:var(--paper)}
.vslot{position:absolute;inset:0;display:grid;place-items:center;text-align:center;padding:10px;
  font-family:var(--disp);font-weight:600;font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase;color:#A6A6AC}
/* 播放角标：白色圆底 + 墨色三角，纯 CSS，不引资源 */
.vcard__p{position:absolute;left:50%;top:50%;width:46px;height:46px;margin:-23px 0 0 -23px;
  border-radius:50%;background:rgba(250,250,248,.92);box-shadow:0 3px 14px rgba(23,23,26,.22);
  transition:transform .2s var(--ease)}
.vcard__p::after{content:"";position:absolute;left:52%;top:50%;transform:translate(-50%,-50%);
  border-left:14px solid var(--ink);border-top:9px solid transparent;border-bottom:9px solid transparent}
.vcard--wait .vcard__p{display:none}
a.vcard:hover .vcard__p{transform:scale(1.08)}
a.vcard:hover img{transform:scale(1.03)}
.vcard img{transition:transform .35s var(--ease)}
.vcard__t{display:block;margin-top:9px;font-family:var(--disp);font-weight:600;
  font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:#8A8A90;line-height:1.55}
@media(max-width:900px){.vrow{grid-template-columns:repeat(2,1fr)}}
@media(max-width:760px){.vcard__t{font-size:11px;letter-spacing:.1em}
  .vcard__p{width:40px;height:40px;margin:-20px 0 0 -20px}}

/* ⚠️ 优先级 bug（2026-08-09 查出）：
   980 断点里写的是 `body{padding-right:0}`（0,0,1），
   而 `body.has-rail{padding-right:var(--rail)}`（0,1,1）specificity 更高，
   **这条重置从来没有生效过**——首页在手机上一直被右侧 rail 的 168px 内边距
   挤成 222px 宽（视口 390 的 57%）。因为首页字号大，肉眼像是"设计如此"。
   下面这条把选择器补齐，专治这一处。 */
@media(max-width:980px){
  body.has-rail{padding-right:0}
  /* rail 一撤，CTA 那条 translateX(50%) 就没有右侧空间了（实测 900/980 溢出 18/15px）。
     它本来是为了让按钮探进 rail，rail 没了就该归位。 */
  .has-rail .nav__links>a.cta,
  .has-rail .nav__links>a.cta:hover{transform:none}
  .has-rail .foot{margin-right:0;padding-right:0}
  .has-rail .nav{margin-right:0}
  .has-rail .nav__in{padding-right:clamp(20px,3.4vw,46px)}
}

/* 9:16 竖图（抖音主页截屏那一格，Adam 2026-08-20）：
   .xshot 原本是给 16:9 宽图用的，比例由 style 属性传进来。 */
/* 竖图在这一排里会太高——列宽收窄，让高度和 bullet 那一栏相称。
   .17 时高 284px，bullet 只有 ~150px，仍然偏高；.13 出来约 218px，接近。
   右边缘仍和其它宽图对齐（padding-right 没动）。 */
.xrow:has(img[style*="9/16"]),
.xrow:has(.xslot[style*="9/16"]){
  grid-template-columns:minmax(0,1fr) calc((100% - var(--xp) - var(--xg)) * .13);
  align-items:start}
/* ⚠️ 窄屏下 .13 会把这一列压到 37px，而占位文字 DOUYIN-PROFILE.JPG 撑到 84px
   —— 整页因此横向溢出 27px。820 以下 .xrow 本来就堆叠成一列，
   这条 :has() 规则必须跟着让位，否则它会盖掉堆叠。 */
@media(max-width:820px){
  .xrow:has(img[style*="9/16"]),
  .xrow:has(.xslot[style*="9/16"]){grid-template-columns:1fr}
  .xrow:has(.xslot[style*="9/16"]) .xshot{max-width:220px}
}
/* 占位态也要吃到 9:16，否则空框还是 16:9 */
.xshot--wait .xslot{width:100%}

/* ============================================================
   Writing 栏目的八格（Adam 2026-08-21）：
   固定四列 × 两行，**每格等宽等高**，左右边缘和 .wrap 严格对齐。
   原来的 .cards--sec 用 auto-fill + minmax，格子数会随宽度变（三列 / 四列
   都可能），八格排出来最后一行会残缺、宽度也对不齐。
   这里改成固定 repeat(4,1fr) + grid-auto-rows:1fr（行高取最高的一格）。
   ============================================================ */
.cards--w{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  grid-auto-rows:1fr;gap:18px;margin-top:30px}
.cards--w .ccard{display:flex;flex-direction:column;height:100%}
.cards--w .ccard__b{display:flex;flex-direction:column;flex:1}
.cards--w .ccard .more{margin-top:auto;padding-top:14px}
.cards--w .ccard h3{font-size:17.5px;line-height:1.28}
.cards--w .ccard p{font-size:13px}
/* 四列一直保持到 1000px：Work 四条正好一行、Writing 八条正好两行。
   一旦掉到三列，Work 的第二行只剩一张卡，那张卡自己决定行高，
   两个网格的卡就不一样高了（Adam 2026-08-22 要求所有框完全一致）。 */
@media(max-width:1000px){.cards--w{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:600px){.cards--w{grid-template-columns:1fr;grid-auto-rows:auto}
  .cards--w .ccard{height:auto}}

/* 长文页：正文比故事页更长，行宽和标题层级单独收一版 */
/* Adam 2026-08-21：文章正文不再单侧排版，铺满 .wrap，左右边距相等。
   .wrap 的 padding-inline 是全站统一的，所以「左右相等」自动成立。
   ⚠️ 代价：1440 下行宽从 68ch 变成约 128 字符。为此把字号抬到 17.5px、
   行距抬到 1.95 —— 行越长，行距必须越大，否则眼睛回不到下一行的行首。 */
.prose--essay{max-width:none}
.prose--essay p,.prose--essay li{font-size:17.5px;line-height:1.95}
/* 题下副题：作者的自嘲、「— Reflections on …」那几行，七篇统一成这一种 */
.prose--essay .edeck{font-family:var(--serif);font-style:italic;font-size:17px;
  line-height:1.7;color:var(--muted);margin:0 0 .5em;max-width:64ch}
.prose--essay .edeck+.edeck{margin-top:-.2em}
.prose--essay .edeck i{font-style:italic}
/* 章节标签：「Part One: …」这类整段加粗的行 */
.prose--essay .elabel{font-family:var(--disp);font-weight:700;font-size:12px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--acc-t);
  margin:2em 0 .8em}
.prose--essay .elabel b{font-weight:700}
.prose--essay h3{font-family:var(--disp);font-weight:var(--dw);font-size:clamp(19px,2.1vw,24px);
  letter-spacing:var(--dls);margin:1.9em 0 .5em;color:var(--ink)}
.prose--essay h4{font-family:var(--disp);font-weight:700;font-size:16px;
  margin:1.5em 0 .4em;color:var(--ink)}
.prose--essay ol,.prose--essay ul{margin:0 0 1.15em;padding-left:1.25em}
.prose--essay li{font-size:16.5px;line-height:1.85;color:#3A3A40;margin:0 0 .5em}
.prose--essay hr{border:0;border-top:1.5px solid var(--line);margin:2.2em 0}
.prose--essay .q{font-family:var(--serif);font-style:italic;font-size:17px;line-height:1.75;
  color:#3A3A40;border-left:3px solid var(--acc);padding-left:18px;margin:1.4em 0}
/* 出处行：中文原标题 + 读的是哪本书 */
.esrc{font-family:var(--mono);font-size:11px;letter-spacing:.09em;color:#8A8A90;
  margin:0 0 26px}

/* Stories 页眉（Adam 2026-08-21「标题一行，副标题一行」）：
   这一页的重点是下面那六张卡，页眉只负责报出页名。
   .phero--slim 的 h1 仍然按大标题排（四行），所以再收一档。 */
.phero--compact{padding-block:clamp(26px,3.4vw,44px) clamp(18px,2.4vw,30px)}
/* .phero__one 有 max-width:66ch —— h1 自己写 max-width:none 是没用的，
   要放开的是外层那个容器。 */
.phero--compact .phero__one{max-width:none}
.phero--compact h1{font-size:clamp(26px,3.4vw,40px);line-height:1.18;max-width:none}
.phero--compact .lead{max-width:none;font-size:clamp(15px,1.5vw,17px);margin-top:10px}

/* Adam 2026-08-21：Experience / Stories 的下拉触发器从 <button> 改成 <a>，
   点击直接进那一页，悬停仍然展开下拉。<a> 自带的下划线和 color 要清掉。 */
a.drop__btn{text-decoration:none}
a.drop__btn:hover{text-decoration:none}

/* 文章页的大标题（Adam 2026-08-21「尽量做成一行」）：
   .phero h1 是 74px + .phero__one 的 66ch 限宽，最长的标题要排三行。
   文章标题最长约 41 个字符（Discrimination is not what we think it is），
   在 1048px 的行宽里，44px 大约刚好一行；再大就保不住。
   ⚠️ 放开的必须是 .phero__one，h1 自己写 max-width 没用（第三十五批那个坑）。 */
.phero--art .phero__one{max-width:none}
.phero--art h1{font-size:clamp(28px,3.6vw,44px);line-height:1.1;max-width:none}
.phero--art .lead{max-width:62ch}

/* Adam 2026-08-21：Stories 页第一个 .band 的上留白太大。
   目标是让「副题底 → 下一个眉标顶」等于「导航底 → 页眉眉标顶」（实测 51px）。
   band 自带 padding-top，页眉自带 padding-bottom，两者相加要落到 51。 */
/* ⚠️ 第四次踩同一个坑：`[data-tight] .phero--slim{padding-bottom:calc(var(--g)/2)}`
   特指度 (0,2,0)，比 `.phero--compact` (0,1,0) 高，我的规则一直没生效
   （量出来两边都是 17px = --g 的一半）。把选择器叠到同级以上才管用。 */
.phero--slim.phero--compact,
[data-tight] .phero--slim.phero--compact{padding-bottom:10px}
.phero--slim.phero--compact + .band,
[data-tight] .phero--slim.phero--compact + .band{padding-top:34px}
/* Adam 2026-08-22：所有跳转框大小完全一致、同行上下对齐。
   上一轮为了消空白改成了 align-items:start（每张卡按内容高），
   现在改回等高——**空白靠把摘要写到差不多长来消除**，不靠拉伸。
   十二条摘要已统一到 167–197 字符（见 build.py 里的 teaser_en）。
   grid-auto-rows:1fr = 同一行等高；align-items:stretch = 卡填满行高。 */
.cards--w{grid-auto-rows:1fr;align-items:stretch}
.cards--w .ccard{height:100%;display:flex;flex-direction:column}
.cards--w .ccard__b{display:flex;flex-direction:column;flex:1}
.cards--w .ccard .more{margin-top:auto;padding-top:14px}

/* 文章页（Adam 2026-08-22）：
   ① 标题到导航的距离和 Stories 页一致（实测 51px）
   ② 正文和摘要都铺满 .wrap，左右边距相等 —— .prose 原来是 64ch 单栏 */
.phero--art{padding-block:clamp(26px,3.4vw,44px) clamp(18px,2.4vw,30px)}
/* 摘要铺满 .wrap 之后，180 字符只排两行、第二行只占 19% —— 全是孤字。
   摘要长度被卡片那边锁死（十二条要一样长），所以只能动字号：
   1048px 下需要文本总宽 ≥1446px 才能让第二行过 38%，
   18.5px → 23px 正好。23px 的题下副题配 44px 标题也站得住。 */
.phero--art .lead{max-width:none;font-size:clamp(17px,2.1vw,23px);line-height:1.62}
.phero--art + .band{padding-top:clamp(20px,2.6vw,34px)}
.phero--art ~ .band .prose,
.band .prose--essay{max-width:none}
.phero--art ~ .band .prose p,
.phero--art ~ .band .prose li{font-size:17.5px;line-height:1.95}

/* 1000–1180 这一档四列最窄（卡宽 225），Work 那组里最长的摘要要多占一行，
   于是 Work 317 / Writing 295 —— 两个网格是分开的，行高对不上。
   给这一档一个共同的 min-height，十二张卡就一样高了。
   （1180 以上两组自然都是 295，不需要这条。） */
/* 三组网格（Work / Writing / Sportsmanship）是三个独立的 grid，
   行高各算各的。差异来自**标题行数**：有的标题一行、有的两行，差一行 ≈ 21px。
   摘要已经统一到 166–197 字符，剩下的只能靠共享下限锁死。
   每一档的值 = 该档里最高的那一组的实测高度。 */
@media(min-width:1001px) and (max-width:1179px){.cards--w .ccard{min-height:317px}}
@media(min-width:1180px){.cards--w .ccard{min-height:295px}}
@media(min-width:601px) and (max-width:1000px){.cards--w .ccard{min-height:297px}}
@media(max-width:600px){.cards--w .ccard{min-height:275px}}

/* ============================================================
   contact 页（Adam 2026-08-22 的四条批注）
   ============================================================ */
/* ② 「an answer」的高亮色：原来是职业藏蓝 #3A4E78，
   在 74px 的粗体上和墨黑几乎分不出来（亮度 .077 vs .01）。
   换成色板里最亮的暖色 —— 陶土红 #B0573C，对纸色 4.7:1 过 AA。
   金色 #C8A96A 只有 2.15:1，连大字号的 3:1 都不到，不能用。 */
/* ⚠️ 第五次：`.phero h1 .acc{color:var(--acc-t)}` 特指度 (0,2,1)，
   压过单独的 `.acc--bright` (0,1,0)。选择器要叠到同级以上。 */
.acc--bright,.phero h1 .acc--bright,h1 .acc--bright{color:#B0573C}
/* ③ 副题按「从上到下逐渐延伸」排：三行手工断行，短 → 中 → 长。
   .lead 默认有 measure 限宽，会把手工断行再折一次，所以要放开。 */
.lead--step{max-width:none}
/* ④ 两张卡的边框、眉标、横线全部走墨黑（原来是五色渐变） */
.card--ink{position:relative;overflow:hidden;border-color:var(--ink)}
.card--ink::before{content:"";position:absolute;left:0;right:0;top:0;height:4px;background:var(--ink)}
.eyebrow--ink{color:var(--ink)}
.eyebrow--ink i{background:var(--ink)}

/* ① Adam 2026-08-22：这一屏的内容要正正落在屏幕中央。
   contact 页眉现在是「文字 + 插画」一整块，让它占满首屏高度并垂直居中。
   min-height 用 svh：移动端浏览器的地址栏会伸缩，vh 会跳。
   矮屏（<640px 高）退回自然高度，否则内容会被挤出屏幕。 */
/* ⚠️ 同样要带 min-width:901px：单栏时文字和插画是上下叠的，
   再强行塞进一屏会把两者一起压扁。（Adam 2026-08-24） */
@media(min-width:901px) and (min-height:640px){
  body[data-fig="contact"] .phero{
    min-height:calc(100svh - var(--navh,64px));
    display:flex;align-items:center;padding-block:clamp(20px,3vw,40px)}
  body[data-fig="contact"] .phero > .wrap{width:100%}
}

/* 长文卡没有眉标，标题要补回眉标原本占的上边距，
   否则标题会顶到顶边那条色条上（Adam 2026-08-22）。 */
.ccard--nok .ccard__b{padding-top:22px}
.ccard--nok h3{margin-top:0}

/* contact 页眉标也改墨黑（Adam 2026-08-22）。
   `.eyebrow--rainbow` 用的是 background-clip:text，
   换成 --ink 之后要把那套渐变彻底关掉，否则文字还是透明的。 */
body[data-fig="contact"] .phero .eyebrow--ink{
  background:none;-webkit-background-clip:border-box;background-clip:border-box;
  color:var(--ink)}
body[data-fig="contact"] .phero .eyebrow--ink i{background:var(--ink)}
/* 标题整体上移一些：眉标和 h1 之间的距离收紧 */
body[data-fig="contact"] .phero h1{margin-top:6px}
body[data-fig="contact"] .phero .eyebrow{margin-bottom:0}

/* ============================================================
   Stories 页收紧（Adam 2026-08-22：留白太多、每段导语都折成残行）
   ============================================================ */
/* ① 栏目导语放开限宽 —— 原来卡在 44ch（1440 下 536px），
   所以每一条都折成「长一行 + 一截短的」。实测五条的文本总宽
   765–926px，都小于 .wrap 的 1048，放开之后各自一行。 */
/* 只在够宽的时候放开：窄屏本来就要折行，放开限宽反而让末行更短。
   1180 是「最长那条导语（926px 文本）能一行装下」的最小宽度。 */
@media(min-width:1180px){body[data-fig="stories"] .band .lead{max-width:none}}

/* ② 段与段之间从 104+104=208px 收到 52+52=104px */
body[data-fig="stories"] .band{padding-block:clamp(30px,3.6vw,52px)}
body[data-fig="stories"] .phero--compact + .band{padding-top:34px}

/* ③ 段内三段间距同比收紧：眉标→标题 16→10，标题→导语 16→10，导语→卡片 30→22 */
body[data-fig="stories"] .band h2{margin-top:10px}
body[data-fig="stories"] .band .lead{margin-top:10px}
body[data-fig="stories"] .band .cards{margin-top:22px}

/* 窄屏（375–430）导语末行只剩 20–30%。text-wrap:pretty 让浏览器
   自己把最后几行匀开，避免残行。不支持的浏览器自动忽略，无副作用。 */
body[data-fig="stories"] .band .lead,
body[data-fig="stories"] .phero .lead{text-wrap:pretty}

/* ============================================================
   More of me（Adam 2026-08-22）：两张名片，版式沿用 contact 的 dt/dd 两列。
   要求「一屏装完、不跨页」，所以行距、字号都比正文紧一档。
   ============================================================ */
.mecards{margin-top:22px}
.melist{display:grid;grid-template-columns:auto 1fr;gap:4px 18px;margin:14px 0 0}
.melist dt{font-family:var(--mono);font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase;color:#8A8A90;padding-top:3px;white-space:nowrap}
.melist dd{margin:0;font-size:14.5px;line-height:1.5;color:var(--ink)}
@media(max-width:640px){
  .melist{grid-template-columns:1fr;gap:2px 0}
  .melist dt{margin-top:10px}
}
/* 这一段整体收紧，保证一屏 */
body[data-fig="stories"] #moreme{padding-block:clamp(26px,3.2vw,46px)}
body[data-fig="stories"] #moreme .lead{margin-top:8px}

/* 窄屏（≤640）名片改单列，两张各按内容高 → 高度不一致。
   .grid2e 是 grid，给它 align-items:stretch + 行高 1fr 会把两张拉齐；
   但单列时两张不在同一行，拉不齐 —— 只能给共同下限。 */
@media(max-width:640px){.mecards .card{min-height:580px}}
/* 641–900 是两列里最窄的一档，dt/dd 折行次数不同 → 两张仍差一行 */
@media(min-width:641px) and (max-width:900px){.mecards .card{min-height:368px}}

/* Adam 2026-08-22：两张名片各八行，要求「一起开始一起结束」。
   左右两栏的 dd 折行次数不同（右边 Research / Tools 会折两行），
   靠 grid 行高只能齐外框，齐不了内部每一行。
   subgrid 让两张 dl 共用同一组行 —— 第 n 行的高度取两边的最大值，
   于是每一条都横向对齐。 */
@media(min-width:641px){
  /* 两张卡各八行，要求「一起开始一起结束」。
     左右 dd 的折行次数不同（右边 Tools 会折两行），
     所以让外层 .mecards 变成 16 行的 grid，两张 dl 用 subgrid 挂上去 ——
     第 n 行的高度取两边的最大值，每一条就横向对齐了。 */
  .mecards{display:grid;grid-template-columns:1fr 1fr;
    grid-template-rows:auto repeat(8,auto);align-items:start}
  .mecards .card{display:grid;grid-row:1 / span 9;grid-template-rows:subgrid}
  .mecards .melist{display:contents}
  .mecards .melist dt{grid-column:1;padding-left:26px}
  .mecards .melist dd{grid-column:2;padding-right:26px}
}

/* 标签列给一个固定宽度，左右两张才会在同一条竖线上起字。
   （subgrid 只同步行高，列宽是各卡自己算的。） */
@media(min-width:641px){
  /* 标签列固定宽 —— subgrid 只同步行高，列宽是各卡自己算的，
     不固定的话左右两张的值列起点会差十几像素。
     138px 是最长标签 PREFERRED NAME 的宽度 + 呼吸。 */
  .mecards .card{grid-template-columns:138px minmax(0,1fr)}
  /* 卡顶那行眉标横跨两列，否则会被挤进 138px 里折行 */
  .mecards .card > .eyebrow{grid-column:1 / -1;white-space:nowrap}
}

/* Adam 2026-08-22：行距缩窄一倍。subgrid 模式下每一行的高度 =
   内容高 + row-gap，所以要同时收 gap 和 dt/dd 的行高。 */
@media(min-width:641px){
  .mecards{row-gap:4px}
  .mecards .melist dt{padding-top:2px;line-height:1.35}
  .mecards .melist dd{line-height:1.4}
}

/* ============================================================
   推荐信引语卡（Adam 2026-08-22）
   三张卡走 .cards--w 的等高网格；引语是主角，署名压在底部。
   ============================================================ */
.ccard--say{cursor:default}
.ccard--say:hover{transform:none;box-shadow:0 4px 0 rgba(23,23,26,.05)}
.sayq{margin:10px 0 0;font-family:var(--serif);font-size:15px;line-height:1.72;
  color:var(--ink);border:0;padding:0}
.sayq b{font-weight:600}
.sayby{margin-top:auto;padding-top:16px;border-top:1.5px solid var(--line);
  display:flex;flex-direction:column;gap:2px}
.sayby b{font-family:var(--disp);font-weight:700;font-size:14px;color:var(--ink)}
.sayby span{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;color:#8A8A90}
.saynote{margin-top:22px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;
  color:#9A9A9E}
/* 只有三张，四列网格会空一格 —— 这一页用三列 */
body[data-char="Business"] .cards--w:has(.ccard--say){grid-template-columns:repeat(3,minmax(0,1fr))}
/* 三列要到 1024 才够宽：901–1023 卡宽只有 264–305，
   职务里最长那行会折出第三行，分隔线就对不齐了。这一档退回单列。 */
@media(max-width:1023px){
  body[data-char="Business"] .cards--w:has(.ccard--say){grid-template-columns:1fr}
}

/* Adam 2026-08-22：三张卡的分隔线要在同一条水平线上。
   引语长度不同 → .sayby 的 margin-top:auto 把署名顶到各自卡底，
   但卡是等高的，所以分隔线位置取决于署名块自己的高度 ——
   第三张的职务折两行，线就比另两张高一截。
   做法：整排用 subgrid，引语区和署名区各占一行，
   引语行取三张里最高的，分隔线自然落在同一条线上。 */
@media(min-width:901px){
  /* 目标：三张卡的分隔线在同一条水平线上。
     卡片等高 + margin-top:auto 只保证「卡底对齐」——署名块自己的高度不同
     （第一张职务折两行），线就差一截。
     做法：引语区用 flex:1 撑开，署名区给一个固定最小高度，
     两块加起来在每张卡里都一样 → 线必然齐。 */
  .ccard--say .ccard__b{display:flex;flex-direction:column;height:100%}
  .ccard--say .sayq{flex:1 1 auto}
  .ccard--say .sayby{margin-top:0}
  /* 三张的职务都写成两行（现职 / 单位全称），高度自然一致 */
  .ccard--say .sayby span{line-height:1.5}
}
}

/* 901–1060 是三列里最窄的一档（卡宽 264），第一张的
   「Formerly Project Manager, Golden Top Grade Asia」会多折一行，
   分隔线又差 16px。这一档把职务字号收半档，三张就都是两行。 */
/* 职务块统一成「恰好两行」：每条都用 <br> 手工断行、禁止自动折行
   （否则窄卡里长的那条会折出第三行），再给容器锁死两行的高度。
   这样三张卡的署名块高度相同 → 分隔线在所有宽度上都同线。 */
/* 三张卡的分隔线要在同一条水平线上。
   卡片等高 + .sayby 的 margin-top:auto 把署名顶到卡底 ——
   只要三张的**署名块高度相同**，线的位置就相同。
   所以三条职务全部写成「两行」（现职 / 单位），高度自然一致。 */
@media(min-width:1024px){
  .ccard--say .sayby span{font-size:9.5px;letter-spacing:.04em;line-height:1.55}
}

/* ============================================================
   More of Me 的红紫渐变（Adam 2026-08-27）
   理由：这一页上半是内容创作（陶土红 #B0573C），下半是小号和说唱
   （紫 #6B4E9E）。一个色代表不了两半，所以整块改成红->紫渐变。
   ⚠️ 只改 More of Me 这一处。别的板块单色不动。
   ============================================================ */
:root{--mm-a:#B0573C;--mm-b:#6B4E9E}

/* 文字渐变：background-clip 是唯一能让文字本身带渐变的办法。
   -webkit- 前缀不能省，Safari 到现在还认它。 */
.mmgrad{background:linear-gradient(90deg,var(--mm-a),var(--mm-b));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent}

/* 下拉里的圆点：从纯色改成渐变小球 */
.dotc--mm{background:linear-gradient(135deg,var(--mm-a),var(--mm-b)) !important}

/* 下拉菜单里那一条的文字 */
.drop__menu a .mmgrad{font-weight:inherit}

/* More of Me 页左上角的眉标：<i> 是那个小方块，文字是后面的部分 */
.eyebrow--mm i{background:linear-gradient(135deg,var(--mm-a),var(--mm-b)) !important}
.eyebrow--mm{background:linear-gradient(90deg,var(--mm-a),var(--mm-b));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent}
/* ⚠️ 眉标的 <i> 必须单独还原成实心 —— 它被父元素的 text-fill-color
   透明化之后会消失。上面那条 background 加 !important 就是为这个。 */

/* Stories 页 More of Me 段右侧那张卡改紫 —— **不在这里做**。
   那两张卡的颜色是行内 style 写死的（--top / color / background），
   CSS 选择器压不过行内样式，得改 build.py 里的标记。留这段注释是为了
   下次别再往这儿加规则然后疑惑为什么不生效。 */
