/* =========================================================
   各页面模块视觉（蓝色系）
   ========================================================= */

/* ---------- Hero：一整屏铺开的画，门牌浮在它上面 ---------- */
.hero{
  position:relative;
  /* 跳出 .shell 那 1220 的框和左右内边距，正正贴到浏览器两边。
     body 上的 overflow-x:hidden 兜住 100vw 比可视区宽那几像素，不会顶出横向滚动条。
     margin-top 是负的：门牌 sticky 在顶上，图要从视口 y=0 开始铺，字才压得住。 */
  width:100vw; margin:calc(-1 * var(--mast-h, 62px)) calc(50% - 50vw) var(--gap);
  min-height:100vh;
  min-height:calc(100svh + var(--mast-h, 62px));   /* 认得 svh 的浏览器跳过上面那条，手机地址栏伸缩不跟着抖 */
  display:grid; place-items:center; overflow:hidden;
  border:none; border-radius:0; box-shadow:none;
  --hero-tint:#4d84ad; --hero-ink:#f4f9ff; --hero-glass:rgba(10,22,36,.42);
}
/* 底色挪到 stage 上：水线以下要真空出来让身后的图透上来，hero 自己带底色就成一条深蓝边了 */
.hero-stage{
  position:absolute; inset:0; background:#16283a;
  /* 直尺画的那种横线不要了 —— 这张画自己以一道水线的形状收口。
     一整张 2880 宽的瓦片铺 200% 宽，所以只有左半截（一个周期 1440）落在屏上：
     左边堆得高、往右一路摊下去、到右边再抬一点，是一道不对称的滩，不是匀称的正弦。
     浪尖在画底 11.6% 处，浪谷几乎贴到边 —— 改深浅记着连着看下面 .hero-swap 那两条。 */
  --shore:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2880 1000' preserveAspectRatio='none'%3E%3Cpath d='M0 930C150 930 200 884 360 884C560 884 620 986 900 986C1140 986 1240 930 1440 930C1590 930 1640 884 1800 884C2000 884 2060 986 2340 986C2580 986 2680 930 2880 930L2880 0L0 0Z' fill='%23fff'/%3E%3C/svg%3E");
  -webkit-mask-image:var(--shore); mask-image:var(--shore);
  /* ★ 按「一屏」对齐，不按「hero 有多高」对齐。hero 是 min-height，字一多就被撑得比屏幕高
     （实测 925 vs 视口 792，多出 133px），水线要是贴着 hero 底边，就整条掉到屏幕外面去了 ——
     四道浪尖全在折叠线以下，她看到的只剩最上面 15px，难怪说「还是不动」。
     把 mask 和浪都改成 svh 单位，水线就永远落在打开页面时那一屏的底边上。
     hero 底边到折叠线之间那截本来就落在 mask 外面，是透的，正好当水面往下延。 */
  -webkit-mask-size:200% 100vh; mask-size:200% 100vh;
  -webkit-mask-size:200% 100svh; mask-size:200% 100svh;
  -webkit-mask-position:0 0; mask-position:0 0;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
}
/* 一张画都没有的时候：整屏给夜海色，字照样站得住 */
.hero.no-art .hero-stage{ background:linear-gradient(180deg,#1e2f42,#16283a 58%,#101d2c); }
.hero.no-art .hero-scrim{ display:none; }
.hero-img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:center 42%;
  opacity:0; transition:opacity .75s ease;
}
.hero-img.is-on{ opacity:1; }
/* 画的呼吸（Ken Burns）：26 秒从 1 走到 1.055 再倒回来，只动 transform，四片浪和 mask 都不受影响。
   幅度不敢大 —— 超过 1.08 人就看出是在推镜头，而不是「这张照片是活的」。
   滚出视口由 core 那个 IntersectionObserver 给 .hero 挂 is-off 停掉（见 style.css 的 .is-off 那组）。 */
@keyframes breathe{ from{ transform:scale(1) } to{ transform:scale(1.055) } }
.hero-img.is-on{ animation:breathe 26s cubic-bezier(.4,0,.6,1) infinite alternate; will-change:transform }
.hero.is-off .hero-img{ animation-play-state:paused }
/* 压一层跟着画面走色的遮罩，字才敢往云上放。不用模糊，模糊一上滚动就掉帧。
   顶上一档特别压深一点 —— 门牌那行白字现在浮在图上。 */
.hero-scrim{
  position:absolute; inset:0;
  background:
    radial-gradient(122% 80% at 50% 46%, rgba(8,20,34,.24), rgba(8,20,34,.62) 82%),
    linear-gradient(180deg, rgba(8,20,34,.6), rgba(8,20,34,.14) 16%, rgba(8,20,34,.06) 38%, rgba(8,20,34,.22) 66%, rgba(8,20,34,.66));
}
.hero[data-tone="bright"] .hero-scrim{ background:
    radial-gradient(122% 80% at 50% 46%, rgba(8,20,34,.34), rgba(8,20,34,.72) 82%),
    linear-gradient(180deg, rgba(8,20,34,.68), rgba(8,20,34,.22) 16%, rgba(8,20,34,.14) 38%, rgba(8,20,34,.3) 66%, rgba(8,20,34,.72)); }
.hero[data-tone="dark"] .hero-scrim{ opacity:.72; }

/* ---------- 水线：四片叠着来回涌的浪 ----------
   来回涌，不是一路漂。`alternate` + 那条两头慢中间快的曲线，四片各自一个节奏（5/7/9/12 秒），
   负延迟把它们错开相位 —— 于是浪头一会儿并齐一会儿岔开，这才是「水在动」。
   一路匀速漂反而看不出来：整条波长铺满一屏，眼睛没有参照，跟静止没区别（我上一版就栽在这儿）。
   ★ 上一版还有第二个坑，藏得更深：这四片当时挂在 .hero-stage 里面，于是跟着被那道静止的 mask 裁了
     —— 浪只剩裁口以上的一小截。拿两帧截图逐像素比，水线那条带只变了 0.1%，等于没动。
     所以它们搬到 stage 外面来了，横跨裁口自己画自己，上面压着画、下面压着透出来的背景。
     mask 依旧一动不动：它每帧重算要把整屏那张画重画一遍，主页一万五千像素滚起来会掉帧。
   ★ 可「像素在变」还是不等于「看得出来在变」：搬到外面之后两帧差已经 18~26% 了，她照样说静止。
     量一下就明白 —— 140px 摊到 20 秒，最慢那片每秒只走 7 像素，比秒针还慢，眼睛追不上。
     所以这一版一起改三样：涌程 140→260px、最快那片 7s→5s、再叠一笔上下颠（--bob），
     让水线本身起伏。左右涌是「漂」，上下颠才是「活」。
   left:-20% + width:140% 是给来回那 260px 留的余量；bottom:-16px 是给它颠上去时留的接底。 */
/* ★ 同样按「一屏」定位，不是按 hero 底边：84svh 起、高 16svh，正好压在上面那道 mask 的裁口上。
   四片浪的浪尖到浪谷 ±42px 是量着裁口挑的，mask 走 svh 它们就得一起走 svh，不然又错开了。 */
.hero-shore{ position:absolute; left:0; top:84vh; top:84svh; bottom:auto; width:100%; height:16vh; height:16svh; z-index:1; pointer-events:none; }
.drift{ position:absolute; left:-20%; bottom:-16px; width:140%; height:100%;
  animation:ripLap var(--rd) cubic-bezier(.55,.5,.45,.5) var(--rl) infinite alternate; }
.drift .df{ stroke:none }
.drift .de{ fill:none; stroke:#f4f9ff; stroke-width:3; stroke-linecap:round }
/* 半透明的纸，一道压一道。不敢调实 —— 底下那张背景图（她可能挑的是自己的一张画）还得透得出来，
   调实了就成一条死色带，水线以下再也不是「身后的图」了。 */
.d-a .df{ fill:color-mix(in srgb,var(--hero-ink) 12%, transparent) } .d-a .de{ opacity:.5 }
.d-b .df{ fill:color-mix(in srgb,var(--hero-ink) 18%, transparent) } .d-b .de{ opacity:.58 }
.d-c .df{ fill:color-mix(in srgb,var(--hero-ink) 26%, transparent) } .d-c .de{ opacity:.66 }
.d-d .df{ fill:color-mix(in srgb,var(--hero-ink) 36%, transparent) } .d-d .de{ opacity:.78 }
/* `var(--bob,0px)` 那个兜底不是摆设：自定义属性一旦没值（写成 undefinedpx 之类），
   整个 translate3d 就作废，四片会一起冻住不动 —— 我这次就先踩过这一脚。 */
@keyframes ripLap{ from{ transform:translate3d(0,0,0) } to{ transform:translate3d(var(--lap,-260px),var(--bob,0px),0) } }
/* 「减弱动效」不该把水冻成死水：她那台 Chrome 常年报 reduce（同机器 Edge 报 no-preference），
   style.css 那条总闸一压，等于整条水线被抹平。她不想要那份偏好替站做主，所以 reduce 的抑制
   现在全挂在 html:not(.is-alive) 上（「该动的都动」，默认开着）—— 只有她把那一枚点掉才走这里：
   水还在涌，只砍行程、放慢速度。
   --lap 只能待在 CSS 里 —— 像 --bob 那样写进行内 style 就压不住了。
   末尾那个 !important 还是留着：压 style.css 里那条 important 的总闸，非 important 赢不了。 */
@media (prefers-reduced-motion:reduce){
  html:not(.is-alive) .drift{ --lap:-160px;
    animation:ripLap calc(var(--rd) * 1.6) cubic-bezier(.55,.5,.45,.5) var(--rl) infinite alternate !important }
}

.hero-center{
  position:relative; z-index:2; text-align:center; color:var(--hero-ink);
  max-width:min(1120px,94%); padding:clamp(34px,6vw,70px) clamp(16px,5vw,44px) clamp(64px,9vw,104px);
}
.hero-plate{
  display:inline-block; padding:9px 20px 9px 25px;
  font-family:var(--font-serif); font-weight:700; font-size:clamp(15px,2.1vw,19px);
  letter-spacing:.42em; color:var(--hero-ink);
  border:1px solid rgba(244,249,255,.5); border-radius:var(--r-xs);
  text-shadow:0 1px 12px rgba(6,18,32,.45);
}
/* 打印机那句：位子先按两行留好，不然每打一句整屏跟着跳一下
   （min-height 那 2.2em = 两行；最长那句 25 个字，1120 的框里 74px 一行能站 13.9 个 → 正好两行）。
   手机端一行站不下 12.5 个字，所以窄屏那条改成留三行 —— 少这一笔，打到我那声呐喊时整屏会往下蹿。 */
.hero-type{
  margin:clamp(14px,2.6vw,26px) 0 14px; font-family:var(--font-serif); font-weight:700;
  font-size:clamp(28px,5.4vw,74px); line-height:1.06; letter-spacing:-.02em; color:var(--hero-ink);
  min-height:2.2em; text-wrap:balance;
  text-shadow:0 2px 26px rgba(6,18,32,.55), 0 1px 2px rgba(6,18,32,.45);
}
@media (max-width:560px){ .hero-type{ font-size:clamp(27px,7.2vw,34px); min-height:3.3em } }
.hero-type::after{
  content:""; display:inline-block; width:.1em; height:.86em; margin-left:.08em;
  vertical-align:-.04em; background:currentColor; opacity:.9;
}
.hero-type.is-hold::after{ animation:typeBlink 1.02s steps(1,end) infinite; }
@keyframes typeBlink{ 0%,49%{ opacity:.9 } 50%,100%{ opacity:0 } }
/* 屏幕阅读器读整句，不跟着一个字一个字念 */
.hero-sr{ position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
.hero-facts{ font-size:12.5px; letter-spacing:.14em; opacity:.88; text-shadow:0 1px 10px rgba(6,18,32,.5); }
.hero-cta-row{ display:flex; gap:12px; justify-content:center; flex-wrap:wrap; margin-top:clamp(18px,2.8vw,28px) }
/* 两枚按钮：药丸收掉，改成稿纸的方角（A3 那条「抬起只留给纸片件」也照办 —— hover 不浮，改填墨）。
   空心的那枚扫上去整块填成纸白，实心的那枚本来就是纸白，只提一档亮度。 */
.hero-cta{
  font-size:14px; letter-spacing:.16em; padding:10px 22px; border-radius:var(--r-s); cursor:pointer;
  border:1px solid rgba(244,249,255,.42); color:var(--hero-ink); background:rgba(10,22,36,.28);
  transition:background var(--t) var(--ease-ink), color var(--t) var(--ease-ink), border-color var(--t) var(--ease-ink);
}
.hero-cta:hover{ background:#f4f9ff; color:#16283a; border-color:#f4f9ff }
.hero-cta.solid{ background:var(--hero-ink); color:#1b3348; border-color:var(--hero-ink) }
.hero-cta.solid:hover{ background:#fff }
/* 磁吸的弹簧：JS 只往 transform 上写偏掉的几个像素，回弹靠这条 transition。
   写在 sections.css 而不是 style.css —— .hero-cta 自己那条 transition 就在这份里，
   后加载的那一份说话才算数，两处都盖不住的话按钮就变成「瞬移」不是「吸过去」。 */
@media (hover:hover) and (pointer:fine){
  .hero-cta, .mast-actions .btn{
    transition:transform .34s cubic-bezier(.34,1.56,.64,1), background var(--t) var(--ease-ink),
               color var(--t) var(--ease-ink), border-color var(--t) var(--ease-ink), box-shadow var(--t) var(--ease-ink);
  }
}
.hero-quote{
  position:relative; margin:clamp(20px,3.4vw,32px) auto 0; max-width:520px;
  padding:15px 56px 15px 22px; border-radius:var(--r-m);
  background:var(--hero-glass); border:1px solid rgba(244,249,255,.22);
}
.hero-quote-text{
  margin:0; font-family:var(--font-hand); color:var(--hero-ink);
  font-size:clamp(15px,2.2vw,19px); line-height:1.72; letter-spacing:.05em;
}
.hero-quote-text.is-new{ animation:rise .42s ease both; }
.hero-shuffle{
  position:absolute; right:11px; top:50%; margin-top:-17px;
  width:34px; height:34px; border-radius:50%; display:grid; place-items:center; cursor:pointer;
  border:1px solid rgba(244,249,255,.38); background:rgba(10,22,36,.34); color:var(--hero-ink); font-size:15px;
  transition:transform .34s ease, background .2s ease;
}
.hero-shuffle:hover{ background:rgba(10,22,36,.6); transform:rotate(180deg); }

/* 邮戳：盖在画面右上角。
   ★ top 要先让开门牌。hero 是 margin-top 负值提到视口 y=0 的，而门牌 sticky 就压在那儿
     （--mast-h 由 core.js 的 measure() 量出来，实测 133px，比从没定义过的 62px 兜底高一大截）。
     贴着 hero 顶放，「合肥 / 日期 / 心屿」那圈字就整个藏在门牌底下了。时钟同理。 */
.hero-postmark{
  position:absolute; right:clamp(12px,3vw,30px); top:calc(var(--mast-h, 62px) + clamp(12px,3vw,24px)); z-index:3;
  width:82px; height:82px; display:grid; place-items:center; text-align:center;
  color:rgba(244,249,255,.82); border:2px solid currentColor; border-radius:50%;
  transform:rotate(-11deg); opacity:.72;
  font-family:var(--font-serif); font-size:10.5px; line-height:1.35; letter-spacing:.04em;
}
.hero-postmark b{ display:block; font-size:15px; letter-spacing:.02em; margin:2px 0; font-variant-numeric:tabular-nums; }
.hero-postmark span{ display:block; font-size:9.5px; letter-spacing:.24em; opacity:.85; }
.hero-postmark::after{ content:""; position:absolute; inset:5px; border:1px solid currentColor; border-radius:50%; opacity:.45; }

.hero-clock{
  position:absolute; left:clamp(12px,3vw,28px); top:calc(var(--mast-h, 62px) + clamp(12px,3vw,24px)); z-index:3;
  display:flex; gap:12px; align-items:flex-end;
  padding:9px 15px; border-radius:var(--r-m);
  background:var(--hero-glass); border:1px solid rgba(244,249,255,.2);
}
.hero-clock .t{ font-family:var(--font-serif); font-size:25px; line-height:1; font-variant-numeric:tabular-nums; color:var(--hero-ink); }
.hero-clock .d{ font-size:11.5px; line-height:1.5; text-align:right; color:rgba(244,249,255,.8); }

.hero-swap{
  /* 抬到水线以上：浪尖最高涌到 84svh 那条带子的顶上，压在那儿就成白字印在浅色背景上，看不见了。
     100% 是 hero 自己的高（撑开后会比一屏高），所以写成「减掉一屏的水线位」而不是减百分比。 */
  position:absolute; left:clamp(12px,3vw,28px); bottom:calc(100% - 84vh + 8px); bottom:calc(100% - 84svh + 8px);
  z-index:3; cursor:pointer;
  font-size:11.5px; letter-spacing:.1em; color:var(--hero-ink);
  padding:6px 14px; border-radius:999px;
  background:var(--hero-glass); border:1px solid rgba(244,249,255,.26);
}
.hero-swap:hover{ background:rgba(10,22,36,.6); }
.hero-scroll{
  position:absolute; right:clamp(12px,3vw,28px); bottom:calc(100% - 84vh + 8px); bottom:calc(100% - 84svh + 8px); z-index:3;
  display:flex; flex-direction:column; align-items:center; gap:7px;
  font-size:11px; letter-spacing:.24em; color:var(--hero-ink); text-decoration:none; opacity:.9;
}
.hero-scroll-line{ width:1px; height:34px; background:linear-gradient(180deg, currentColor, transparent); animation:dive 2.4s ease-in-out infinite; }
@keyframes dive{ 0%,100%{ transform:scaleY(.5); opacity:.45 } 50%{ transform:scaleY(1); opacity:1 } }

@media (max-width:720px){
  /* 手机上还是一整屏，只是四角那几件小东西收小，别挤到标语头上 */
  .hero-postmark{ width:64px; height:64px; font-size:9px; }
  .hero-postmark b{ font-size:12px; }
  .hero-clock .t{ font-size:20px; }
  .hero-scroll{ display:none; }
  .hero-center{ padding-bottom:76px }
  .hero-quote{ padding-right:22px; padding-bottom:52px; }
  .hero-shuffle{ top:auto; bottom:10px; right:10px; margin-top:0; }
}

/* 心帖卷首：她自己存的一叠画，手动翻。不裁 —— 按自己的比例走，只限个高。
   「▦ 背景」里那条浮层透明度对它只出一半的力（.45 ~ 1）：画淡到看不清，就谁也看不成了。 */
.nine-banner{ margin:0 0 var(--gap); text-align:center; line-height:0 }
.nine-banner[data-art]{ cursor:zoom-in }   /* 只有一张时退回安静的一张，照样能点开 */
.nb-stage{ position:relative; display:inline-block; max-width:100%; border-radius:var(--r-l); cursor:zoom-in;
  opacity:calc(.45 + var(--veil,1) * .55); transition:opacity .2s ease;
  touch-action:pan-y; outline:none }
.nb-stage:focus-visible{ box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 42%, transparent) }
.nb-slide{ display:block; width:auto; height:auto; max-width:100%; max-height:clamp(150px,44vh,400px);
  border-radius:var(--r-l); border:1px solid var(--paper-edge); box-shadow:var(--shadow-m) }
.nb-in{ animation:nbIn .3s var(--ease-ink) }
@keyframes nbIn{ from{ opacity:0; transform:translateX(12px) } }
.nb-nav{ position:absolute; top:50%; transform:translateY(-50%); width:30px; height:44px; display:grid;
  place-items:center; padding:0; border:1px solid var(--paper-edge); border-radius:999px; cursor:pointer;
  font:inherit; font-size:20px; line-height:1; color:var(--ink-soft); opacity:.72;
  background:color-mix(in srgb,var(--paper-hi) 82%, transparent); box-shadow:var(--shadow-s);
  transition:opacity var(--t-fast), color var(--t-fast), transform var(--t) var(--ease-spring) }
.nb-nav:hover{ opacity:1; color:var(--accent) }
.nb-nav:active{ transform:translateY(-50%) scale(.94) }
.nb-prev{ left:9px } .nb-next{ right:9px }
.nb-foot{ display:flex; flex-wrap:wrap; gap:10px 12px; align-items:center; justify-content:center;
  margin-top:11px; line-height:1.6 }
.nb-dots{ display:flex; gap:7px }
.nb-dot{ width:9px; height:9px; padding:0; border-radius:50%; cursor:pointer; border:1px solid var(--line);
  background:color-mix(in srgb,var(--paper-hi) 70%, transparent);
  transition:background var(--t-fast), border-color var(--t-fast), transform var(--t) var(--ease-spring) }
.nb-dot:hover{ transform:scale(1.3) }
.nb-dot.on{ background:var(--accent); border-color:var(--accent) }
.nb-n{ font-family:var(--font-mono); font-size:11.5px; color:var(--muted) }
.nb-foot .dim{ font-size:11.5px; color:var(--muted) }
.nb-foot code{ background:var(--paper-lo); padding:1px 5px; border-radius:4px }
@media (max-width:720px){ .nb-slide{ max-height:clamp(130px,36vh,320px) } .nb-nav{ width:26px; height:38px; font-size:17px } }

/* ---------- 身份卡 ---------- */
.id-card{ text-align:center; padding:30px 22px 22px; }
.avatar{
  position:relative; width:104px; height:104px; margin:-58px auto 12px;
  border-radius:50%; overflow:hidden; background:var(--paper-lo);
  border:4px solid var(--paper-hi); box-shadow:var(--shadow-l); transform:rotate(-3deg);
  transition:transform var(--t-slow) var(--ease-spring); cursor:pointer;
}
.id-card:hover .avatar{ transform:rotate(0deg) scale(1.03); }
.avatar img{ width:100%; height:100%; object-fit:cover; }
.avatar .fallback{ width:100%; height:100%; }
/* 扫到头像时从下面推上来的一条：压在圆底上被裁成一段弦，跟微博/QQ 那个「换头像」一个做法。
   触屏没得扫，就一直挂着。 */
.av-hint{
  position:absolute; left:0; right:0; bottom:0; padding:6px 0 8px;
  font-size:11px; letter-spacing:.16em; line-height:1; text-align:center;
  color:var(--paper-hi); background:color-mix(in srgb,var(--ink) 58%, transparent);
  opacity:0; transform:translateY(100%); transition:opacity var(--t), transform var(--t); pointer-events:none;
}
.avatar:hover .av-hint, .avatar:focus-visible .av-hint{ opacity:1; transform:none }
@media (hover:none){ .av-hint{ opacity:1; transform:none } }

/* 换头像的面板（core.js 的 avatarPanel） */
.av-thumbs{ display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin:14px 0 4px }
.av-thumb{
  position:relative; padding:0; line-height:0; cursor:pointer; overflow:hidden;
  border-radius:50%; border:1px solid var(--line); background:var(--paper-lo);
  transition:transform var(--t) var(--ease-spring), border-color var(--t) }
.av-thumb img{ display:block; width:100%; aspect-ratio:1; object-fit:cover }
.av-thumb:hover{ transform:translateY(-2px) }
.av-thumb.on{ border-color:var(--accent); box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 26%, transparent) }
.av-thumb.on::after{
  content:"✓"; position:absolute; left:50%; bottom:5px; transform:translateX(-50%);
  width:18px; height:18px; border-radius:50%; display:grid; place-items:center;
  font-size:11px; line-height:1; color:var(--paper-hi); background:var(--accent);
  box-shadow:0 0 0 2px var(--paper-hi) }
.av-foot{ margin-top:12px; text-align:right }
.id-name{ font-family:var(--font-serif); font-size:23px; letter-spacing:.12em; }
.id-en{ font-family:var(--font-hand); font-size:16px; letter-spacing:.08em; color:var(--pencil); margin-top:1px; }
.id-motto{
  margin:13px auto 0; padding:9px 6px; color:var(--ink-soft);
  border-top:1px dashed var(--line-dash); border-bottom:1px dashed var(--line-dash); max-width:262px;
}
.id-facts{ display:flex; justify-content:center; gap:7px; margin-top:14px; flex-wrap:wrap; }
.id-fact{ font-size:12px; color:var(--ink-soft); background:var(--paper-lo); border:1px solid var(--line);
  border-radius:3px 3px 12px 3px; padding:3px 10px; letter-spacing:.04em; }
.id-fact i{ font-style:normal; color:var(--seal); opacity:.75; margin-right:3px; }
.id-links{ display:flex; justify-content:center; gap:9px; margin-top:16px; flex-wrap:wrap; }
.id-link{
  min-width:34px; height:30px; padding:0 11px; border-radius:var(--r-s); display:grid; place-items:center;
  background:var(--paper-hi); border:1px solid var(--line); box-shadow:var(--shadow-s);
  font-size:12px; color:var(--ink-soft); transition:.18s;
}
.id-link:hover{ transform:translateY(-3px) rotate(-4deg); border-color:var(--accent); color:var(--accent); }
.id-count{ display:flex; margin-top:18px; padding-top:14px; border-top:var(--rule-seam); }
.id-count div{ flex:1; }
.id-count b{ display:block; font-family:var(--font-serif); font-size:20px; }
.id-count span{ font-size:11.5px; color:var(--muted); letter-spacing:.06em; }

/* ---------- 今日 / 小条 ---------- */
.today{ display:flex; flex-direction:column; gap:10px; }
.today-row{ display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:13.5px; }
.today-row span{ color:var(--muted); }
.today-row b{ font-family:var(--font-serif); font-size:16px; }

/* ---------- 人生进度 ---------- */
.life-grid{ display:grid; grid-template-columns:170px minmax(0,1fr); gap:26px; align-items:center; }
@media (max-width:640px){ .life-grid{ grid-template-columns:1fr; } }
.ring{ position:relative; display:grid; place-items:center; }
.ring svg{ width:100%; max-width:170px; transform:rotate(-90deg); }
.ring .track{ fill:none; stroke:var(--line); stroke-width:11; }
.ring .bar{ fill:none; stroke:var(--accent); stroke-width:11; stroke-linecap:round; transition:stroke-dashoffset 1s cubic-bezier(.2,.8,.2,1); }
.ring .center{ position:absolute; text-align:center; }
.ring .center b{ display:block; font-family:var(--font-serif); font-size:30px; line-height:1.1; }
.ring .center span{ font-size:11px; color:var(--muted); letter-spacing:.14em; }
.bars{ display:flex; flex-direction:column; gap:14px; }
.bar-row .bar-top{ display:flex; justify-content:space-between; font-size:12.5px; margin-bottom:5px; }
.bar-row .bar-top span{ color:var(--muted); letter-spacing:.05em; }
.bar-row .bar-top b{ font-family:var(--font-serif); font-variant-numeric:tabular-nums; }
.bar-track{ height:9px; border-radius:999px; background:var(--paper-lo); border:1px solid var(--line); overflow:hidden; }
.bar-fill{ height:100%; border-radius:999px;
  background:repeating-linear-gradient(45deg, var(--accent) 0 6px, color-mix(in srgb,var(--accent) 68%, #fff) 6px 12px);
  transition:width 1.1s cubic-bezier(.2,.8,.2,1); }
.life-note{ margin:16px 0 0; font-size:12.5px; color:var(--muted); font-family:var(--font-serif); }

/* ---------- 关于我 ---------- */
.about-p{ margin-bottom:18px; }
.about-p h4{ font-family:var(--font-serif); font-size:15px; margin-bottom:4px; color:var(--accent); letter-spacing:.06em; }
.ap-body{ color:var(--ink-soft); margin:0; }
.facts{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:10px; margin-top:6px; }
.fact{ padding:11px 13px; border-radius:var(--r-s); background:var(--paper-lo); border:1px solid var(--line); transition:.18s; margin:0; }
.fact:hover{ transform:translateY(-2px) rotate(-.6deg); border-color:var(--accent); box-shadow:var(--shadow-m); }
.fact dt{ font-size:11.5px; color:var(--muted); letter-spacing:.1em; }
.fact dd{ margin:2px 0 0; font-size:14.5px; font-weight:600; }

/* ---------- 便利贴 ---------- */
.notes{ display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:18px; }
.note{
  position:relative; min-height:150px; padding:20px 16px 16px;
  background:linear-gradient(160deg,var(--nc,#dbe9f6),color-mix(in srgb,var(--nc,#dbe9f6) 76%, #fff));
  border-radius:2px 2px 14px 2px; box-shadow:var(--shadow-m);
  transform:rotate(var(--rot,0deg)); transition:.22s ease;
}
.note::after{ content:""; position:absolute; right:0; bottom:0; width:26px; height:26px;
  background:linear-gradient(135deg,transparent 50%,rgba(0,0,0,.09) 50%); }
.note:hover{ transform:rotate(0deg) translateY(-5px); box-shadow:var(--shadow-lift); }
.note h4{ font-family:var(--font-serif); font-size:17px; margin-bottom:6px; color:#1d3a55; }
.note-body{ margin:0; font-size:13.5px; color:#3c5a76; line-height:1.8; }
[data-theme="night"] .note h4{ color:#e6f1fa; }
[data-theme="night"] .note-body{ color:#a9c3da; }
[data-theme="night"] .note::after{ background:linear-gradient(135deg,transparent 50%,rgba(0,0,0,.4) 50%); }
.note .tape{
  position:absolute; top:-11px; left:50%; width:74px; height:22px; transform:translateX(-50%) rotate(-4deg);
  background:repeating-linear-gradient(45deg, rgba(255,255,255,.55) 0 6px, rgba(255,255,255,.2) 6px 12px);
  box-shadow:0 2px 4px rgba(30,60,90,.16);
}

/* ---------- 技能 ---------- */
.skill{ margin-bottom:15px; }
.skill:last-child{ margin-bottom:0; }
.skill-top{ display:flex; align-items:baseline; gap:10px; font-size:14px; margin-bottom:6px; }
.skill-top .n{ font-weight:600; }
.skill-top .note{ font-size:12px; color:var(--muted); margin-left:auto; text-align:right; }
.ticks{ display:flex; gap:4px; height:14px; }
.tick{ flex:1; border-radius:var(--r-xs); background:var(--paper-lo); border:1px solid var(--line); }
.tick.on{ background:var(--sc,var(--accent)); border-color:transparent; opacity:.92; }

/* ---------- 时间轴 ---------- */
.tl{ position:relative; padding-left:26px; }
.tl::before{ content:""; position:absolute; left:7px; top:4px; bottom:4px; border-left:2px dashed var(--line-dash); }
.tl-item{ position:relative; margin-bottom:20px; }
.tl-item:last-child{ margin-bottom:0; }
.tl-item::before{
  content:""; position:absolute; left:-26px; top:5px; width:14px; height:14px; border-radius:50%;
  background:radial-gradient(circle at 34% 32%, #ffffff9e, transparent 42%), var(--kc,var(--accent));
  box-shadow:0 2px 5px rgba(30,60,90,.35); border:2px solid var(--paper-hi);
}
.tl-date{ font-family:var(--font-serif); font-size:12.5px; letter-spacing:.1em; color:var(--muted); }
.tl-title{ font-size:16px; font-weight:700; margin:1px 0 2px; }
.tl-org{ font-size:13px; color:var(--accent); }
.tl-text{ font-size:13.5px; color:var(--ink-soft); margin:4px 0 0; }
.tl-kind{ display:inline-block; font-size:10.5px; padding:1px 8px; border-radius:999px; margin-left:8px;
  border:1px solid var(--line); color:var(--muted); vertical-align:2px; }

/* ---------- 打卡热力图 ---------- */
.hm{ overflow-x:auto; padding-bottom:6px; }
.hm-row{ display:flex; align-items:center; gap:12px; margin-bottom:9px; }
.hm-name{ width:62px; flex:none; font-size:13px; color:var(--ink-soft); text-align:right; }
.hm-cells{ display:flex; gap:3px; }
.hm-cell{
  width:12px; height:12px; border-radius:var(--r-xs); flex:none; cursor:pointer;
  background:var(--paper-lo); box-shadow:inset 0 0 0 1px var(--line); transition:transform .12s ease;
}
.hm-cell.on{ background:var(--hc); box-shadow:none; }
.hm-cell.today{ border:1px solid var(--ink); }
.hm-cell:hover{ transform:scale(1.5); position:relative; z-index:2; }
.hm-legend{ display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--muted); margin-top:12px; }
.hm-legend i{ width:11px; height:11px; border-radius:var(--r-xs); display:inline-block; }
.hm-sum{ font-size:12.5px; color:var(--muted); margin:8px 0 0; }

/* ---------- 人生清单 ---------- */
.wish{ display:flex; align-items:flex-start; gap:11px; padding:9px 0; border-bottom:var(--rule-row); }
.wish:last-of-type{ border-bottom:none; }
.wish-box{ width:19px; height:19px; flex:none; margin-top:4px; border-radius:var(--r-s);
  border:1.5px solid var(--line-dash); background:var(--paper-hi); position:relative; transition:.18s; cursor:pointer; }
.wish-box:hover{ border-color:var(--accent); transform:rotate(-6deg); }
.wish.done .wish-box{ background:var(--teal); border-color:var(--teal); }
.wish.done .wish-box::after{ content:""; position:absolute; left:5px; top:1px; width:5px; height:10px;
  border:solid #fff; border-width:0 2px 2px 0; transform:rotate(42deg); }
.wish-txt{ font-size:14.5px; }
.wish.done .wish-txt{ color:var(--muted); text-decoration:line-through; text-decoration-color:var(--teal); }
.wish-del{ margin-left:auto; border:none; background:none; color:var(--muted); font-size:16px; opacity:0; transition:.18s; padding:0 4px; cursor:pointer; }
.wish:hover .wish-del{ opacity:.6; }
.wish-del:hover{ opacity:1; color:var(--rose); }
.wish-add{ display:flex; gap:9px; margin-top:14px; }
.wish-add input, .field{
  flex:1; padding:8px 12px; border-radius:var(--r-s); font:inherit; font-size:14px;
  background:var(--paper-hi); border:1px dashed var(--line-dash); color:var(--ink); outline:none;
}
.wish-add input:focus, .field:focus{ border-style:solid; border-color:var(--accent); }

/* ---------- 现在 ---------- */
.now-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:18px; }
.now-col h4{ font-family:var(--font-serif); font-size:14px; letter-spacing:.1em; color:var(--accent); margin-bottom:8px; }
.now-col li{ font-size:13.5px; color:var(--ink-soft); padding:4px 0 4px 16px; position:relative; }
.now-col li::before{ content:""; position:absolute; left:2px; top:12px; width:6px; height:6px; border-radius:50%; background:var(--mist); }

/* =========================================================
   手帐（文章）
   ========================================================= */
/* 筛选：和导航同一套语言 —— 文字 + 墨线，不要一片药丸 */
.tabs{ display:flex; gap:2px; flex-wrap:wrap; margin-bottom:18px; border-bottom:1px dashed var(--line-dash); padding-bottom:0; }
.tab{
  position:relative; padding:6px 12px 8px; font-size:13.5px; cursor:pointer; letter-spacing:.05em;
  background:none; border:none; color:var(--muted);
  transition:color var(--t) var(--ease-ink), transform var(--t) var(--ease-ink);
}
.tab:hover{ color:var(--ink); transform:translateY(-1px); }
.tab.on{ color:var(--accent); font-weight:700; }
.tab.on::after{
  content:""; position:absolute; left:8px; right:8px; bottom:-1px; height:2px; border-radius:var(--r-xs);
  background:linear-gradient(90deg, var(--accent), color-mix(in srgb,var(--accent) 30%, transparent));
  animation:tabIn .3s var(--ease-ink);
}
@keyframes tabIn{ from{ transform:scaleX(.2); opacity:0 } to{ transform:none; opacity:1 } }
.tab i{ font-style:normal; opacity:.55; font-size:11px; margin-left:4px; font-variant-numeric:tabular-nums; }

.post{
  display:grid; grid-template-columns:196px minmax(0,1fr); gap:20px; align-items:center;
  padding:14px 16px 14px 14px; border-radius:var(--r-m);
  /* 底色跟着「▦ 背景」里那条浮层透明度走，算法和播放器卡片一样：纸按 --veil 掺透明，
     字不跟着淡（淡了读不掉）。图另算 —— 见下面 .post-cover。 */
  background:linear-gradient(178deg,
    color-mix(in srgb,var(--paper-hi) calc(var(--veil,1) * 100%), transparent),
    color-mix(in srgb,var(--paper-lo) calc(var(--veil,1) * 100%), transparent));
  border:1px solid var(--paper-edge); box-shadow:var(--shadow-m), inset 0 1px 0 var(--hair);
  transition:transform var(--t) var(--ease-ink), box-shadow var(--t) var(--ease-ink), border-color var(--t); cursor:pointer;
}
.post:hover{ box-shadow:var(--shadow-m), inset 0 1px 0 var(--hair), inset 2px 0 0 var(--accent); border-color:var(--line); }
.post:nth-child(even) .post-cover{ order:2; }
.post-bare{ grid-template-columns:minmax(0,1fr) }   /* 没配图就整条留给字，不摆「没有配图」那块空牌 */
.post-cover{
  aspect-ratio:16/10; border-radius:var(--r-s); overflow:hidden; background:var(--paper-lo);
  border:1px solid var(--line); display:grid; place-items:center; color:var(--muted); font-size:12px;
  font-family:var(--font-hand); letter-spacing:.1em;
  /* 和心帖卷首同一档：滑杆拉到底图也不会全没，只出一半的力 */
  opacity:calc(.45 + var(--veil,1) * .55); transition:opacity .2s ease;
}
.post-cover img{ width:100%; height:100%; object-fit:cover; transition:transform var(--t-slow) var(--ease-ink); }
.post-cover[data-tall] img{ object-position:center 24% }   /* 竖图塞进 16:10 的格，取景往上挪，别切头 */
.post:hover .post-cover img{ transform:scale(1.05); }
.post-aside-img{ margin-top:22px }
.post-aside-img img{ width:100%; border-radius:var(--r-s) }
.post-title{ font-size:19px; font-family:var(--font-serif); letter-spacing:.06em; display:flex; align-items:center; gap:8px; }
.badge{ font-size:10.5px; padding:1px 8px; border-radius:var(--r-xs); background:var(--seal); color:#fdf6f4; font-family:var(--font-body); letter-spacing:.08em; }
.post-ex{ font-size:13.5px; color:var(--ink-soft); margin:7px 0 10px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.post-meta{ display:flex; flex-wrap:wrap; gap:7px 12px; font-size:12px; color:var(--muted); align-items:center; }
.post-meta .dot{ width:3px; height:3px; border-radius:50%; background:var(--line-dash); display:inline-block; }
.post-list{ display:flex; flex-direction:column; gap:16px; }
@media (max-width:640px){ .post{ grid-template-columns:1fr; gap:12px } .post:nth-child(even) .post-cover{ order:0 } }

.article-head{ border-bottom:var(--rule-seam); padding-bottom:18px; margin-bottom:22px; position:relative; }
.article-no{ position:absolute; right:0; top:-8px; font-family:var(--font-hand); font-size:16px; color:var(--pencil); letter-spacing:.1em; }
/* 章首图：横图铺满，竖图收着走，总之一句 —— 不裁她的图 */
.plate{ margin:22px 0 26px; text-align:center; cursor:zoom-in; }
.plate img{
  display:inline-block; width:auto; height:auto; max-width:100%; max-height:min(56vh,440px);
  border-radius:var(--r-s); border:1px solid var(--paper-edge); box-shadow:var(--shadow-m); transition:box-shadow .22s ease;
}
.plate:hover img{ box-shadow:var(--shadow-lift); }
.plate figcaption{ font-family:var(--font-hand); font-size:12.5px; color:var(--muted); margin-top:9px; letter-spacing:.04em; }
.plate figcaption i{ font-style:normal; opacity:.6; margin-left:9px; }
details.src > summary{
  cursor:pointer; list-style:none; display:inline-flex; align-items:center; gap:8px;
  padding:6px 14px; border-radius:999px; font-size:13px; color:var(--ink-soft);
  background:var(--paper-lo); border:1px dashed var(--line-dash); transition:.18s;
}
details.src > summary::-webkit-details-marker{ display:none; }
details.src > summary::before{ content:"▸"; font-size:11px; transition:transform .2s; }
details.src[open] > summary::before{ transform:rotate(90deg); }
details.src > summary:hover{ border-color:var(--accent); color:var(--accent); }
details.src > .ml{ margin-top:14px; padding:14px 16px; border-radius:var(--r-s);
  background:var(--paper-lo); border:1px solid var(--line); font-size:14px; line-height:1.9;
  max-height:60vh; overflow:auto; }
.article-title{ font-family:var(--font-serif); font-size:clamp(24px,3.4vw,34px); letter-spacing:.14em; line-height:1.35; }
.article-meta{ display:flex; flex-wrap:wrap; gap:7px 15px; font-size:12.5px; color:var(--muted); margin-top:11px; letter-spacing:.06em; }
.article-meta b{ color:var(--ink-soft); font-weight:600; font-variant-numeric:tabular-nums; }
.archive-group{ margin-bottom:20px; }
.archive-group h4{ font-family:var(--font-serif); font-size:15px; color:var(--accent); letter-spacing:.1em; margin-bottom:6px; }
.archive-group a{ display:block; padding:6px 10px; border-radius:var(--r-s); font-size:14px; transition:.15s; cursor:pointer; }
.archive-group a:hover{ background:var(--paper-lo); color:var(--accent); }
.archive-group span{ color:var(--muted); font-size:12px; margin-left:8px; }

/* =========================================================
   随笔
   ========================================================= */
.sb{ display:flex; flex-direction:column; }
.sb-item{ padding:18px 0; border-bottom:var(--rule-row); position:relative; }
.sb-item:last-child{ border-bottom:none; }
.sb-head{ display:flex; align-items:center; gap:10px; margin-bottom:8px; }
.sb-av{ width:34px; height:34px; border-radius:50%; overflow:hidden; background:var(--paper-lo); border:2px solid var(--paper-hi); box-shadow:var(--shadow-s); flex:none; display:grid; place-items:center; font-size:11px; color:var(--muted); }
.sb-av img{ width:100%; height:100%; object-fit:cover; }
.sb-name{ font-weight:600; font-size:14px; }
.sb-time{ font-size:11.5px; color:var(--muted); margin-left:auto; }
.sb-text{ font-size:15px; line-height:1.9; white-space:pre-wrap; margin:0 0 8px; }
.sb-imgs{ display:flex; gap:8px; flex-wrap:wrap; }
.sb-imgs img{ width:120px; height:90px; object-fit:cover; border-radius:var(--r-s); border:2px solid var(--paper-hi); box-shadow:var(--shadow-m); cursor:zoom-in; transition:.2s; }
.sb-imgs img:hover{ transform:translateY(-3px) rotate(-1.5deg); }
.sb-foot{ display:flex; gap:14px; align-items:center; font-size:12px; color:var(--muted); margin-top:8px; }
.sb-tag{ font-size:11px; padding:1px 8px; border-radius:999px; background:var(--paper-lo); border:1px solid var(--line); }
.sb-form{ display:flex; flex-direction:column; gap:9px; margin-bottom:6px; }
.sb-form textarea{ min-height:74px; resize:vertical; font:inherit; }
.sb-form-row{ display:flex; gap:9px; align-items:center; flex-wrap:wrap; }

/* =========================================================
   收藏
   ========================================================= */
.jar{ margin-bottom:26px; }
.jar:last-child{ margin-bottom:0; }
.jar-head{ display:flex; align-items:baseline; gap:10px; margin-bottom:12px; }
.jar-name{ font-family:var(--font-serif); font-size:17px; letter-spacing:.05em; }
.jar-count{ font-size:11px; color:var(--muted); opacity:.85; }
.jars{ display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); gap:14px; }
.jar-card{
  padding:14px 16px; border-radius:var(--r-m); background:linear-gradient(178deg,var(--paper-hi),var(--paper-lo));
  border:1px solid var(--paper-edge); box-shadow:var(--shadow-s); transition:.2s; position:relative;
}
.jar-card:hover{ transform:translateY(-3px) rotate(-.4deg); box-shadow:var(--shadow-lift); border-color:var(--accent); }
.jar-card a{ color:var(--accent); font-size:14.5px; font-weight:600; word-break:break-all; }
.jar-card p{ font-size:13px; color:var(--ink-soft); margin:5px 0 8px; line-height:1.75; }
.jar-card .jar-meta{ display:flex; gap:8px; align-items:center; font-size:11.5px; color:var(--muted); flex-wrap:wrap; }
/* 「想画进画里的东西」那一罐：点「看看它」把那只兽请出来 —— 不垫底板、不加描边，
   线稿直接落在卡片这张纸上，位置排在说明和标签之间 */
.jar-crit{ display:flex; justify-content:center; margin:2px 0 5px; }
.jar-crit[hidden]{ display:none; }
.crit-live-box{ display:block; width:min(132px,36vw); height:min(132px,36vw); }
.quote-card{
  padding:16px 18px; border-radius:var(--r-m); background:var(--paper-lo); border-left:4px solid var(--teal);
  font-family:var(--font-serif); font-size:15px; line-height:1.9; color:var(--ink-soft); position:relative;
}
.quote-card span{ display:block; font-family:var(--font-body); font-size:12px; color:var(--muted); margin-top:8px; }

/* =========================================================
   相册
   ========================================================= */
.albums{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:18px; }
.photos{ display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:16px; }
.photo{
  background:var(--paper-hi); border:1px solid var(--paper-edge); border-radius:var(--r-s);
  padding:8px 8px 12px; box-shadow:var(--shadow-m); transition:.24s ease; cursor:zoom-in;
}
.photo:nth-child(3n){ transform:rotate(1.1deg); }
.photo:nth-child(3n+1){ transform:rotate(-1deg); }
.photo:hover{ transform:rotate(0) translateY(-6px) scale(1.02); box-shadow:var(--shadow-lift); z-index:2; }
.photo-frame{ aspect-ratio:4/3; border-radius:var(--r-xs); overflow:hidden; background:var(--paper-lo); display:grid; place-items:center; color:var(--muted); font-size:12px; border:1px dashed var(--line-dash); }
.photo-frame img{ width:100%; height:100%; object-fit:cover; }
.photo-cap{ font-size:13px; margin:9px 2px 2px; }
.photo-date{ font-size:11px; color:var(--muted); margin:0 2px; }
.photo .photo-x{ position:absolute; top:12px; right:12px; z-index:2; opacity:0;
  background:var(--paper-hi); border-radius:50%; width:22px; height:22px; line-height:1; }
.photo:hover .photo-x{ opacity:.75; }
.photo{ position:relative; }
.photo-frame.filled{ border-style:solid; }
.lightbox{ background:none; border:none; padding:0; max-width:min(1000px,94vw); }
.lightbox img{ max-height:78vh; margin:0 auto; border-radius:var(--r-s); box-shadow:var(--shadow-l); }
.lightbox p{ text-align:center; color:#dceaf5; margin:12px 0 0; font-size:14px; }
.lb-close{ position:absolute; top:18px; right:22px; color:#dceaf5; font-size:26px; background:none; border:none; cursor:pointer; }
.lightbox .lb-note{ color:#8fb6d8; font-size:12.5px; margin-top:5px; letter-spacing:.06em; }
/* 摊开的是一沓画时，底下这一条给计数和两枚真能点的箭头（← → 也认，见 core.js 的 keydown）。
   只有一张时整条不出现 —— 「1 / 1」是装饰，不是信息。 */
.lightbox:has(.lb-nav) img{ max-height:71vh; }
.lb-nav{ display:flex; align-items:center; justify-content:center; gap:18px; margin-top:12px; }
.lb-count{ color:#8fb6d8; font-size:13px; letter-spacing:.14em; min-width:62px; text-align:center; }
.lb-arrow{ width:44px; height:38px; border-radius:var(--r-s); cursor:pointer; font-size:16px; line-height:1;
  color:#dceaf5; background:color-mix(in srgb,#dceaf5 12%, transparent);
  border:1px solid color-mix(in srgb,#dceaf5 26%, transparent);
  transition:background-color var(--t-fast), border-color var(--t-fast); }
.lb-arrow:hover{ background:color-mix(in srgb,#dceaf5 22%, transparent); border-color:color-mix(in srgb,#dceaf5 46%, transparent); }

/* =========================================================
   画集：一栏一栏自己排，竖图横图都按原比例占位，谁也不裁谁
   ========================================================= */
.art-wall{ display:flex; gap:12px; align-items:flex-start; margin:0 0 var(--gap); }
.art-col{ flex:1 1 0; min-width:0; display:flex; flex-direction:column; gap:12px; }
.art-item{
  position:relative; margin:0; cursor:zoom-in; overflow:hidden;
  border-radius:var(--r-s); border:1px solid var(--paper-edge);
  background:var(--paper-lo); box-shadow:var(--shadow-m);
}
.art-item img{ display:block; width:100%; height:auto; transition:transform .55s ease; }
.art-item:hover img{ transform:scale(1.035); }
.art-cred{
  position:absolute; left:0; right:0; bottom:0; padding:20px 10px 8px;
  font-size:11px; letter-spacing:.05em; color:#eaf3fb; opacity:0; transition:opacity .24s ease;
  background:linear-gradient(180deg, rgba(8,20,34,0), rgba(8,20,34,.74));
}
.art-item:hover .art-cred{ opacity:.95; }
.art-filter{ display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:var(--ink-soft); cursor:pointer; }.art-filter input{ accent-color:var(--teal); width:14px; height:14px; }
.art-note{ font-size:12px; margin:10px 0 0; }
.art-more{ border-style:dashed; color:var(--muted); }
@media (max-width:880px){ .art-wall, .art-col{ gap:9px; } }

/* =========================================================
   友链
   ========================================================= */
.banner{
  position:relative; overflow:hidden; border-radius:var(--r-l); padding:26px 28px; margin-bottom:var(--gap);
  background:linear-gradient(120deg,color-mix(in srgb,var(--indigo) 88%, #000),color-mix(in srgb,var(--teal) 80%, #000));
  color:#eaf4fb; box-shadow:var(--shadow-l);
}
.banner small{ font-size:12px; letter-spacing:.2em; opacity:.75; }
.banner h2{ font-family:var(--font-serif); font-size:clamp(20px,3vw,28px); margin:8px 0 6px; letter-spacing:.05em; }
.banner p{ font-size:13px; opacity:.82; margin:0; }
.banner .btn{ position:absolute; right:24px; bottom:22px; background:rgba(255,255,255,.16); border-color:rgba(255,255,255,.3); color:#f2f9ff; }
.steps{ counter-reset:s; display:flex; flex-direction:column; gap:12px; }
.steps li{ display:flex; gap:12px; align-items:flex-start; font-size:14px; color:var(--ink-soft); }
.steps li::before{
  counter-increment:s; content:"0" counter(s); flex:none; width:26px; height:26px; border-radius:50%;
  display:grid; place-items:center; font-size:11px; font-family:var(--font-serif);
  background:var(--accent); color:#f2f9ff;
}
[data-theme="night"] .steps li::before{ color:#0e1620; }
.friends{ display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:16px; }
.friend{
  border-radius:var(--r-m); overflow:hidden; background:linear-gradient(178deg,var(--paper-hi),var(--paper-lo));
  border:1px solid var(--paper-edge); box-shadow:var(--shadow-m); transition:.22s;
}
.friend:hover{ transform:translateY(-4px); box-shadow:var(--shadow-lift); }
.friend-cover{ height:96px; background:var(--paper-lo); display:grid; place-items:center; color:var(--muted); font-size:12px; overflow:hidden; }
.friend-cover img{ width:100%; height:100%; object-fit:cover; }
.friend-body{ padding:12px 14px 14px; display:flex; gap:10px; align-items:center; }
.friend-av{ width:36px; height:36px; border-radius:50%; flex:none; overflow:hidden; background:var(--paper-lo); border:2px solid var(--paper-hi); box-shadow:var(--shadow-s); }
.friend-av img{ width:100%; height:100%; object-fit:cover; }
.friend b{ font-size:14px; display:block; }
.friend span{ font-size:12px; color:var(--muted); }

/* =========================================================
   日志
   ========================================================= */
.log-day{ margin-bottom:22px; }
.log-day h4{ font-family:var(--font-serif); font-size:15px; letter-spacing:.1em; color:var(--accent); margin-bottom:9px; }
.log-items{ display:flex; flex-direction:column; border:1px solid var(--line); border-radius:var(--r-s); overflow:hidden;
  /* 一整块稿纸，行与行之间压一道发线 —— 以前每条日志是一张浮空小卡，一屏十几张就成了一摞便利贴 */
  background:color-mix(in srgb,var(--paper-lo) calc(var(--veil,1) * 62%), transparent); }
.log-items li{
  display:flex; gap:10px; padding:9px 13px; font-size:14px; color:var(--ink-soft);
  border-bottom:var(--rule-row); transition:background-color var(--t-fast), box-shadow var(--t-fast);
}
.log-items li:last-child{ border-bottom:none }
.log-items li:hover{ background-color:color-mix(in srgb,var(--paper-hi) 42%, transparent); box-shadow:inset 2px 0 0 var(--accent) }
.log-items li i{ font-style:normal; color:var(--accent); font-family:var(--font-serif); font-size:12px; }

/* =========================================================
   统计
   ========================================================= */
/* 便当格：打破整齐的一排四个，才不像后台仪表盘 */
.tiles{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:12px; }
.tile{
  padding:15px 14px 13px; border-radius:var(--r-m); text-align:left; position:relative;
  background:linear-gradient(178deg,var(--paper-hi),var(--paper-lo)); border:1px solid var(--paper-edge);
  box-shadow:var(--shadow-s), inset 0 1px 0 var(--hair);
  transition:transform var(--t) var(--ease-ink), box-shadow var(--t) var(--ease-ink), border-color var(--t);
}
.tile:nth-child(1){ grid-column:span 2; }
.tile:nth-child(6){ grid-column:span 2; }
.tile:hover{ transform:translateY(-3px) rotate(-.4deg); box-shadow:var(--shadow-lift); border-color:var(--mist); }
.tile b{ display:block; font-family:var(--font-serif); font-size:30px; line-height:1.15; color:var(--accent); font-variant-numeric:tabular-nums; }
.tile:nth-child(1) b{ font-size:40px; }
.tile span{ font-size:12px; color:var(--muted); letter-spacing:.1em; }
.tile small{ display:block; font-size:14px; color:var(--pencil); font-family:var(--font-hand); margin-top:3px; line-height:1.3; }
@media (max-width:900px){
  .tiles{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .tile:nth-child(1),.tile:nth-child(6){ grid-column:span 2; }
}
.cloud{ display:flex; flex-wrap:wrap; gap:10px 14px; align-items:baseline; }
.cloud a{ cursor:pointer; transition:.18s; line-height:1.4; }
.cloud a:hover{ color:var(--accent); transform:translateY(-2px); }
.dist{ display:flex; flex-direction:column; gap:11px; }
.dist-row{ display:grid; grid-template-columns:80px 1fr 42px; gap:10px; align-items:center; font-size:13px; }
.dist-row span{ color:var(--muted); text-align:right; }
.dist-row b{ font-family:var(--font-serif); text-align:right; }

/* =========================================================
   留言板
   ========================================================= */
.gb-form{ display:flex; flex-direction:column; gap:10px; margin-bottom:8px; }
.gb-row{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.gb-row .field{ flex:1 1 180px; }
.gb-count{ font-size:11.5px; color:var(--muted); font-family:var(--font-mono,ui-monospace,monospace); letter-spacing:.04em; }
.gb-head{ display:flex; align-items:baseline; gap:10px; margin:2px 0 12px; }
.gb-head b{ font-family:var(--font-serif); font-size:16px; }
.gb-head .dim{ font-size:12px; }
/* 规则那张：压成一小块，别抢留言本身 */
.gb-rules{ margin-top:14px; padding:11px 14px; border-radius:var(--r-s);
  /* 比卡片再淡一档（62%），但跟着同一条滑杆走：背景调淡时它不该比邻居更白 */
  background:color-mix(in srgb,var(--paper-lo) calc(var(--veil,1) * 62%), transparent);
  border:1px dashed var(--line-dash); }
.gb-rules b{ display:block; font-size:12.5px; color:var(--ink-soft); margin-bottom:5px; letter-spacing:.02em; }
.gb-rules p{ margin:0 0 3px; font-size:12px; line-height:1.75; color:var(--muted); }
.gb-rules p:last-child{ margin-bottom:0; }
.gb-list{ display:flex; flex-direction:column; gap:14px; }
.gb-item{ display:grid; grid-template-columns:38px minmax(0,1fr); gap:11px;
  padding:14px 16px; border-radius:var(--r-m);
  /* 和 .card 一样跟着「▦ 背景」那条滑杆（--veil）掺透明：整块板子的底色都该听同一个旋钮，
     不然把背景调淡了只有留言这几张卡还死白一片。字和边框不跟着淡。 */
  background:linear-gradient(178deg,
    color-mix(in srgb,var(--paper-hi) calc(var(--veil,1) * 100%), transparent),
    color-mix(in srgb,var(--paper-lo) calc(var(--veil,1) * 100%), transparent));
  border:1px solid var(--paper-edge); box-shadow:var(--shadow-s); transition:.2s;
}
/* 抬起留给拍立得和画集那种「一张纸被揭走」的件；留言是一条条贴在板上的纸，
   原来这儿的 translateY 还被下面两条 nth-child 的旋转盖掉，只有三分之一那几行真的在抬。 */
.gb-item:hover{ box-shadow:var(--shadow-m), inset 2px 0 0 var(--accent); border-color:var(--line) }
.gb-item:nth-child(3n){ transform:rotate(.4deg); }
.gb-item:nth-child(3n+1){ transform:rotate(-.5deg); }
.gb-main{ min-width:0; }   /* 栅格里不加这句，长网址会把整列顶宽 */
.gb-top{ display:flex; align-items:center; gap:9px; margin-bottom:7px; flex-wrap:wrap; }
.gb-av{ width:38px; height:38px; border-radius:50%; background:var(--mist); color:#12304a; display:grid; place-items:center; font-size:15px; font-family:var(--font-serif); flex:none; }
.gb-who{ font-weight:600; font-size:14px; }
/* 归属地：一个不抢眼的小芯片，和名字并排 —— 别的留言板都这么做，看着才知道留言是活人留的 */
.gb-place{ font-size:11px; color:var(--muted); padding:1px 8px; border-radius:999px;
  background:color-mix(in srgb,var(--mist) 40%, transparent); box-shadow:inset 0 0 0 1px var(--line); }
/* 注册徽章：名字后面压一枚小朱印，用的是站里现成的 --seal，不为新东西引进新颜色 */
.gb-member{ font-size:10.5px; line-height:1.6; color:var(--seal); padding:0 6px; border-radius:var(--r-xs);
  font-family:var(--font-serif); letter-spacing:.06em;
  background:color-mix(in srgb,var(--seal) 7%, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--seal) 42%, transparent); }
/* 服务器给的那个名字不让改：虚线框 + 压暗的底，和旁边能编辑的格子一眼分得开 */
.field.is-locked{ border-style:dashed; cursor:default; color:var(--ink-soft);
  background:color-mix(in srgb,var(--mist) 14%, transparent); }
.gb-date{ font-size:11.5px; color:var(--muted); margin-left:auto; }
/* overflow-wrap 那句：body 上是 overflow-x:hidden，留言里贴一长串网址会直接裁没，看着像她没写完 */
.gb-text{ font-size:14.5px; line-height:1.85; white-space:pre-wrap; overflow-wrap:anywhere; margin:0; }
.gb-reply{ margin-top:9px; padding:8px 12px; border-radius:var(--r-s); background:color-mix(in srgb,var(--teal) 12%, transparent);
  border-left:3px solid var(--teal); }
.gb-rep-top{ display:flex; align-items:baseline; gap:7px; font-size:12px; color:var(--muted); margin-bottom:5px; }
.gb-rep-top b{ color:var(--teal); font-weight:600; }
.gb-rep-top i{ font-style:normal; }
/* 她回的那一条，署名行右端落一枚朱印 —— 像她在那行名字边上按的手印。
   跟着 flex 那一排走，不浮起来：浮的话印只有 24px 高，压不住底下正文的第一行，还是会盖字。
   单字印是她那套「心屿之印」的缩小版，别换成图标或 emoji。 */
.gb-rep-seal{ margin-left:auto; align-self:center; flex:none; width:24px; height:24px; display:grid; place-items:center;
  font-family:var(--font-serif); font-size:14px; line-height:1; color:var(--seal);
  border:1.4px solid var(--seal); border-radius:var(--r-xs); transform:rotate(-8deg); opacity:.85;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--seal) 26%, transparent); }
/* 落印只在「这一页刚摊开」时演：切页时 html.enter 是摘掉的（见 style.css 第 13 节），
   不然 View Transition 拍到的新页面快照里这枚印还没落，交叉淡出之后它才补一下。 */
html.enter .gb-rep-seal{ animation:stamp .5s var(--ease-spring) backwards .35s; }
.gb-rep-text{ font-size:13px; line-height:1.75; color:var(--ink-soft); white-space:pre-wrap; overflow-wrap:anywhere; }
.gb-acts{ display:flex; gap:4px; }
.gb-act{ border:1px solid var(--line); background:color-mix(in srgb,var(--paper-hi) 70%, transparent); color:var(--muted);
  cursor:pointer; font-size:11.5px; padding:2px 9px; border-radius:999px; opacity:.62; transition:.18s; }
.gb-act:hover{ opacity:1; color:var(--ink); box-shadow:var(--shadow-s); }
.gb-act.is-del:hover{ color:var(--rose); border-color:color-mix(in srgb,var(--rose) 40%, var(--line)); }
.gb-del{ border:none; background:none; color:var(--muted); cursor:pointer; font-size:14px; opacity:.5; }
.gb-del:hover{ opacity:1; color:var(--rose); }

.friend-body .gb-del{ margin-left:auto; }
.friend .gb-del:hover{ opacity:1; color:var(--rose); }
select.field{ -webkit-appearance:none; appearance:none; cursor:pointer; }

/* =========================================================
   统计：月度柱
   ========================================================= */
.months{ display:flex; align-items:flex-end; gap:8px; height:170px; padding-top:14px; }
.mo{ flex:1; display:flex; flex-direction:column; align-items:center; gap:5px; min-width:0; }
.mo-w{ font-size:10.5px; color:var(--muted); font-family:var(--font-serif); height:13px; }
.mo-stack{ width:100%; max-width:30px; min-height:3px; border-radius:5px 5px 2px 2px; position:relative;
  background:repeating-linear-gradient(45deg, var(--accent) 0 5px, color-mix(in srgb,var(--accent) 62%, #fff) 5px 10px);
  opacity:.86; transition:height .8s cubic-bezier(.2,.8,.2,1); }
.mo-stack:hover{ opacity:1; }
.mo-dot{ position:absolute; left:50%; top:-9px; width:6px; height:6px; margin-left:-3px; border-radius:50%;
  background:var(--teal); box-shadow:0 0 0 2px var(--paper-hi); }
.mo-lab{ font-size:10.5px; color:var(--muted); white-space:nowrap; }

/* ---------- toast：一张从底下递上来的小纸条 ---------- */
.toast{
  position:fixed; left:50%; bottom:34px; transform:translate(-50%,26px) rotate(-.6deg); z-index:80;
  padding:11px 22px; border-radius:4px 4px 10px 10px; font-size:13.5px; letter-spacing:.03em;
  background:var(--ink); color:var(--paper-hi); box-shadow:var(--shadow-l);
  opacity:0; pointer-events:none; max-width:88vw; text-align:center;
  transition:transform .42s var(--ease-spring), opacity .3s var(--ease-ink);
}
.toast.show{ opacity:1; transform:translate(-50%,0) rotate(-.6deg); }

/* ---------- 在循环的歌 ---------- */
.np{ display:flex; flex-direction:column; gap:11px; }
.np-row{ display:grid; grid-template-columns:26px minmax(0,1fr) auto; gap:4px 12px; align-items:baseline;
  padding:9px 12px; border-radius:var(--r-s); background:color-mix(in srgb,var(--paper-lo) 62%, transparent);
  border:1px solid var(--line); transition:transform var(--t) var(--ease-ink), border-color var(--t); }
.np-row:hover{ transform:translateX(4px); border-color:var(--mist); }
.np-play{ grid-row:1; color:var(--muted); font-size:13px; cursor:pointer; line-height:1;
  transition:color var(--t) var(--ease-ink), transform var(--t) var(--ease-spring); }
.np-play:hover{ color:var(--accent); transform:scale(1.18) }
.np-play svg{ width:15px; height:15px }
.np-row.is-now{ border-color:var(--accent); background:color-mix(in srgb,var(--mist) 18%, transparent) }
.np-row.is-now .np-play{ color:var(--accent) }
.np-info{ min-width:0 }
.np-t{ font-size:14.5px; font-weight:600; }
.np-a{ font-size:12.5px; color:var(--muted); }
.np-why{ grid-column:1/-1; font-family:var(--font-hand); font-size:15.5px; color:var(--pencil); line-height:1.5; }
.np-tip{ margin:12px 0 0; font-size:11.5px; line-height:1.7 }
/* 频谱条：不出声就不动。原来是无条件一直跳 —— 那是骗人 */
.np-eq{ display:flex; align-items:flex-end; gap:2px; height:15px; }
.np-eq i{ width:3px; background:var(--accent); border-radius:1px; opacity:.3; transform:scaleY(.5);
  transform-origin:bottom; animation:none; }
.np-row.is-playing .np-eq i, .dock[data-state="play"] .np-eq i{ opacity:.75; animation:eq 1.1s ease-in-out infinite; }
.np-eq i:nth-child(1){ height:7px } .np-eq i:nth-child(2){ height:13px; animation-delay:.18s }
.np-eq i:nth-child(3){ height:5px; animation-delay:.36s } .np-eq i:nth-child(4){ height:10px; animation-delay:.54s }
@keyframes eq{ 0%,100%{ transform:scaleY(.45) } 50%{ transform:scaleY(1) } }

/* ---------- 跑出去的下午 ---------- */
.run{ display:flex; align-items:flex-end; gap:26px; flex-wrap:wrap; }
.run-big{ font-family:var(--font-serif); }
.run-big b{ font-size:42px; line-height:1; color:var(--accent); font-variant-numeric:tabular-nums; }
.run-big span{ font-size:12.5px; color:var(--muted); letter-spacing:.1em; margin-left:5px; }
.run-track{ flex:1; min-width:200px; }
.run-line{ width:100%; height:56px; }
.run-line path{ fill:none; stroke:var(--mist); stroke-width:2; stroke-linecap:round;
  stroke-dasharray:520; stroke-dashoffset:520; animation:draw 1.5s var(--ease-ink) forwards .2s; }
.run-line circle{ fill:var(--seal); opacity:0; animation:dotIn .4s var(--ease-ink) forwards 1.4s; }
@keyframes draw{ to{ stroke-dashoffset:0 } }
@keyframes dotIn{ to{ opacity:.9 } }
.run-notes{ display:flex; gap:20px; flex-wrap:wrap; margin-top:12px; font-size:13px; color:var(--ink-soft); }
.run-notes i{ font-style:normal; color:var(--muted); letter-spacing:.08em; margin-right:5px; font-size:11.5px; }

/* ---------- 18. 心帖卷首 ---------- */
.nine-intro .quote{ min-height:34px; }
.nine-years{ display:flex; gap:12px; flex-wrap:wrap; }
.nine-year{ flex:1 1 116px; min-width:104px; padding:11px 12px 13px;
  border:1px dashed var(--line-dash); border-radius:var(--r-m);
  background:color-mix(in srgb,var(--paper-lo) 42%, transparent); }
.nine-year.is-tbd{ border-style:solid; border-color:color-mix(in srgb,var(--pencil) 42%, transparent);
  background:repeating-linear-gradient(45deg,transparent 0 5px,color-mix(in srgb,var(--pencil) 7%,transparent) 5px 6px); }
.nine-ytag{ font-family:var(--font-hand); font-size:20px; color:var(--ink-soft); letter-spacing:.06em; }
.nine-year.is-tbd .nine-ytag{ font-size:16px; color:var(--pencil); }
.nine-dots{ display:flex; flex-direction:column; gap:6px; margin-top:10px; }
.nine-dot{ font:inherit; font-family:var(--font-serif); font-size:16px; letter-spacing:.12em; text-align:left;
  padding:5px 10px; border-radius:var(--r-s); border:1px solid var(--line); cursor:pointer;
  background:var(--paper-hi); color:var(--accent);
  transition:transform var(--t) var(--ease-ink), border-color var(--t), box-shadow var(--t); }
.nine-dot:hover{ transform:translateX(3px); border-color:var(--accent); box-shadow:var(--shadow-m); }
.nine-dot::after{ content:attr(data-date); font-family:var(--font-body); font-size:11px; letter-spacing:.04em;
  color:var(--pencil); margin-left:9px; }
.nine-dot:not([data-date]){ border-style:dashed; color:var(--ink-soft); }

.nine-toc{ padding-top:22px; }
.nine-list{ list-style:none; margin:0; padding:0; }
.nine-row{ display:grid; grid-template-columns:auto auto minmax(0,1fr) auto auto; gap:14px; align-items:center;
  padding:11px 0; border-bottom:var(--rule-row); cursor:pointer; }
.nine-row:last-child{ border-bottom:none; }
.nine-num{ font-family:var(--font-hand); font-size:15px; color:var(--pencil); letter-spacing:.05em; }
.nine-char{ font-family:var(--font-serif); font-size:27px; line-height:1; letter-spacing:.08em; color:var(--ink);
  transition:color var(--t) var(--ease-ink), transform var(--t) var(--ease-spring); }
.nine-row:hover .nine-char{ color:var(--accent); transform:translateY(-1px); }
.nine-side{ font-family:var(--font-hand); font-size:16.5px; color:var(--pencil); letter-spacing:.03em;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.nine-meta{ font-size:12px; color:var(--muted); white-space:nowrap; }
.nine-meta .dot{ width:3px; height:3px; border-radius:50%; background:var(--line-dash); display:inline-block; margin:0 7px; vertical-align:2px; }
.nine-tbd{ font-style:normal; color:var(--pencil); border-bottom:1px dashed var(--pencil); padding-bottom:1px; }
/* 后端替她收起来的正文：说清是「不给看」，不是「没写」 */
.priv-tag{ color:var(--pencil); font-size:12.5px; border-bottom:1px dashed var(--pencil); padding-bottom:1px; }
.priv-note{
  margin-top:6px; padding:20px 22px; border:1px dashed var(--line-dash); border-radius:var(--r-m);
  background:var(--paper-lo); color:var(--ink-soft); font-size:14px; line-height:2; letter-spacing:.04em;
}
.nine-crit{ width:40px; height:40px; opacity:.42;
  transition:opacity var(--t-slow), transform var(--t) var(--ease-spring); }
.nine-row:hover .nine-crit{ opacity:.95; transform:translateX(-4px) rotate(-3deg); }
/* 扫过一行浮出的章首图：跟手的那张小纸片。不接点击，永远压在门牌底下（38 < 40），
   transform 由 nine.js 的 rAF 一行一行写，所以这里绝不能给 transform 加 transition —— 会和插值打架。 */
.nine-peek{
  position:fixed; left:0; top:0; z-index:38; width:216px; height:150px; pointer-events:none;
  border-radius:var(--r-m); overflow:hidden; opacity:0; background:var(--paper-hi);
  border:1px solid var(--paper-edge); box-shadow:var(--shadow-l);
  transition:opacity .2s var(--ease-ink); will-change:transform;
}
.nine-peek.is-on{ opacity:1 }
.nine-peek img{ width:100%; height:100%; object-fit:cover }
@media (hover:none){ .nine-peek{ display:none } }

/* ---------- 19. 心气 ---------- */
.mood-clear{ --mc:#c9a227; --mc-ink:#38290a; }
.mood-cloud{ --mc:#b7c9da; --mc-ink:#22323f; }
.mood-fog{ --mc:#dbe6ee; --mc-ink:#2b3a45; }
.mood-rain{ --mc:#4a7fae; --mc-ink:#eef6ff; }
.mood-frost{ --mc:#8ab3d6; --mc-ink:#0f2637; }
.mood-storm{ --mc:#43507f; --mc-ink:#e9e7f8; }
[data-theme="dusk"] .mood-clear{ --mc:#d4b13f; --mc-ink:#2e2409; }
[data-theme="dusk"] .mood-cloud{ --mc:#a6b8d0; --mc-ink:#1c2634; }
[data-theme="dusk"] .mood-fog{ --mc:#c4d1e2; --mc-ink:#232e3c; }
[data-theme="dusk"] .mood-frost{ --mc:#7fa8cf; --mc-ink:#0d2033; }
[data-theme="night"] .mood-clear{ --mc:#e3c05a; --mc-ink:#211703; }
[data-theme="night"] .mood-cloud{ --mc:#6f8296; --mc-ink:#0c141c; }
[data-theme="night"] .mood-fog{ --mc:#516677; --mc-ink:#dbe8f4; }
[data-theme="night"] .mood-rain{ --mc:#6fa8dc; --mc-ink:#081a2b; }
[data-theme="night"] .mood-frost{ --mc:#9fc8e8; --mc-ink:#0a1f31; }
[data-theme="night"] .mood-storm{ --mc:#8b95d8; --mc-ink:#0d1026; }

.mood-chips{ display:flex; gap:9px; flex-wrap:wrap; }
.mood-chip{ font:inherit; font-family:var(--font-serif); font-size:17px; letter-spacing:.06em;
  display:inline-flex; align-items:center; justify-content:center; gap:5px;
  width:62px; height:46px; border-radius:10px; cursor:pointer;
  border:1px solid var(--line); background:var(--paper-lo); color:var(--ink-soft);
  transition:transform var(--t) var(--ease-spring), background var(--t), color var(--t), border-color var(--t), box-shadow var(--t); }
.mood-chip:hover{ transform:translateY(-2px); border-color:var(--mc); color:var(--mc); }
.mood-chip.on{ background:var(--mc); border-color:var(--mc); color:var(--mc-ink); box-shadow:var(--shadow-m); }
/* 符号只是给那个字配一张脸，颜色跟着字走（点中就是底色上的墨），别自己去够 --mc */
.m-mark{ width:14px; height:14px; flex:none; display:inline-block; vertical-align:-2px; pointer-events:none; }
.mood-chip .m-mark{ width:16px; height:16px; vertical-align:0; }
.mood-note{ margin-top:14px; }
.mood-pickbar{ display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-top:12px; }

.m-legend{ display:flex; gap:14px 18px; flex-wrap:wrap; margin:2px 0 14px; }
.m-lg{ font-size:12.5px; color:var(--muted); display:inline-flex; align-items:center; gap:6px; }
.m-swatch{ width:12px; height:12px; border-radius:var(--r-xs); display:inline-block; background:var(--mc, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 14%, transparent); }
.m-swatch.is-vacant{ background:repeating-linear-gradient(45deg,transparent 0 3px,color-mix(in srgb,var(--pencil) 30%,transparent) 3px 4px); }

.m-row{ display:flex; align-items:center; gap:10px; }
.m-mlab{ flex:none; width:42px; font-size:12px; color:var(--muted); text-align:right; letter-spacing:.04em; }
.m-cells{ display:flex; gap:3px; flex:1; min-width:0; }
.m-cell{ flex:1 1 0; min-width:0; height:16px; padding:0; border:none; border-radius:var(--r-xs); cursor:pointer;
  background:repeating-linear-gradient(45deg,transparent 0 4px,color-mix(in srgb,var(--pencil) 13%,transparent) 4px 5px);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--pencil) 22%, transparent);
  transition:transform var(--t-fast) var(--ease-spring), box-shadow var(--t-fast); }
.m-cell.has{ background:var(--mc); box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 10%, transparent); }
.m-cell:hover{ transform:scaleY(1.5); }
.m-cell.is-today{ box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 10%, transparent), 0 0 0 2px var(--seal); }
.note-cut{ display:block; font-size:15px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

@media (max-width:720px){
  .nine-crit{ display:none; }
  .nine-row{ grid-template-columns:auto auto minmax(0,1fr) auto; }
  .nine-side{ display:none; }
  /* 色带以前是一个月压成一整行：390 的屏上一格只剩 6×13px，一年 365 个格一个都点不中。
     手机上改成一行 16 格、排两圈，格子变成约 16×22 —— 全部日子仍然一眼看全，不用横向滚。 */
  .m-cells{ display:grid; grid-template-columns:repeat(16,minmax(0,1fr)); gap:2px; }
  .m-cell{ flex:none; width:auto; height:22px; }
  .m-mlab{ width:30px; }
  .m-row{ gap:8px; }
}

/* ---------- 切换背景面板（sky.js） ---------- */
.bg-head{ display:flex; align-items:baseline; gap:12px; margin:0 0 12px }
.bg-head h3{ font-size:17px; margin:0; letter-spacing:.06em }
.bg-head span{ font-size:12px; color:var(--muted) }
.bg-close{ margin-left:auto; font-size:20px; line-height:1; cursor:pointer; color:var(--muted); align-self:center }
.bg-close:hover{ color:var(--accent) }

/* ---------- 登录 / 注册（core.js 的 openGate） ----------
   一张脸只做一件事，输入框压在稿纸那种一条一条的横线上，四周留一条沟放蝴蝶和霜。 */
.gate{ position:relative; max-width:392px; padding:22px 26px 18px }
.gate-head{ display:flex; align-items:center; gap:9px; margin:0 0 2px }
.gate-head svg{ width:24px; height:24px; flex:none }
.gate-head b{ font-family:var(--font-serif); font-size:17px; letter-spacing:.16em; color:var(--indigo) }
.gate-rule{ flex:1; height:1px; background:linear-gradient(90deg,color-mix(in srgb,var(--ink) 22%, transparent),transparent) }
.gate .bg-close{ position:absolute; right:12px; top:7px; margin-left:0 }
.gate-face{ position:relative; z-index:1 }
.gate-face[hidden]{ display:none }
.gate-sub{ font-size:12.5px; color:var(--muted); line-height:1.75; margin:0 0 15px }
.gate-fld{ display:block; margin:0 0 12px }
.gate-fld > span{ display:flex; align-items:baseline; gap:8px; margin-bottom:1px;
  font-size:12px; letter-spacing:.08em; color:var(--ink-soft) }
.gate-fld > span i{ font-style:normal; margin-left:auto; font-size:11px; letter-spacing:0;
  color:var(--muted); opacity:.8 }
.gate-fld input{ width:100%; padding:6px 2px 5px; font:inherit; font-size:15.5px; color:var(--ink);
  background:none; border:none; border-radius:0; outline:none;
  border-bottom:1px solid color-mix(in srgb,var(--ink) 30%, transparent);
  transition:border-color var(--t) var(--ease-ink), box-shadow var(--t) var(--ease-ink) }
.gate-fld input:focus{ border-bottom-color:var(--accent);
  box-shadow:0 1px 0 0 color-mix(in srgb,var(--accent) 34%, transparent) }
.gate-fld input::placeholder{ color:var(--pencil); opacity:.6 }
.gate-go{ width:100%; margin-top:5px; padding:11px 0; font-size:15px; letter-spacing:.24em; justify-content:center }
.gate-err{ font-size:12.5px; color:var(--seal); margin:9px 0 0 }
.gate-switch{ margin:15px 0 0; padding-top:12px; border-top:var(--rule-seam);
  text-align:center; font-size:12.5px; color:var(--muted) }
.gate-to{ font:inherit; font-size:12.5px; color:var(--accent); cursor:pointer;
  border-bottom:1px solid transparent; padding:1px 0 }
.gate-to:hover{ border-bottom-color:var(--accent) }

/* 框边那一条沟里落着的点缀（svg 由 core.js 的 paintGateDeco 填进来）。
   顶上那几枚钉在框角；底下那一排跟着内容走 —— 弹窗一滚，钉在底下的会飘到按钮上，所以那一排必须站在文字后面。 */
.gate-deco{ position:absolute; inset:0; z-index:0; pointer-events:none }
.gd{ position:absolute; display:block; opacity:.5 }
.gd svg{ display:block; width:100%; height:100% }
.gd-b1{ left:7px; top:7px; width:19px; height:19px }
.gd-f1{ right:40px; top:11px; width:13px; height:13px; opacity:.42; color:var(--sky-flake) }
.gd-f2{ right:84px; top:27px; width:10px; height:10px; opacity:.38; color:var(--sky-flake) }
.gate-band{ display:flex; align-items:flex-end; justify-content:space-between; gap:10px;
  margin-top:16px; padding:0 4px 1px; pointer-events:none; position:relative; z-index:0 }
.gb{ position:relative; display:block; opacity:.5 }
.gb svg{ display:block; width:100%; height:100% }
.gb-b1{ width:24px; height:24px }
.gb-b2{ width:17px; height:17px; opacity:.6 }
.gb-f1,.gb-f2,.gb-f3{ color:var(--sky-flake) }
.gb-f1{ width:11px; height:11px; opacity:.4 }
.gb-f2{ width:14px; height:14px; opacity:.34 }
.gb-f3{ width:9px; height:9px; opacity:.44 }
.gd-b1,.gb-b1,.gb-b2,.gd-f1,.gd-f2,.gb-f1,.gb-f2,.gb-f3{ animation:gdDrift 9s ease-in-out infinite }
.gd-b1{ animation-duration:8s }
.gb-b1{ animation-duration:7.4s; animation-delay:-1.4s }
.gb-b2{ animation-duration:10.4s; animation-delay:-3.1s }
.gd-f1{ animation-duration:11.6s; animation-delay:-5.2s }
.gd-f2{ animation-duration:13.4s; animation-delay:-9.1s }
.gb-f1{ animation-duration:9.2s; animation-delay:-4.6s }
.gb-f2{ animation-duration:12.6s; animation-delay:-7.3s }
.gb-f3{ animation-duration:11s; animation-delay:-2.2s }
@keyframes gdDrift{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-4px) } }
.bg-tabs,.bg-sky{ display:flex; flex-wrap:wrap; gap:8px; align-items:center }
.bg-lbl{ margin:0 0 9px; font-size:11.5px; font-weight:700; letter-spacing:.14em; color:var(--muted) }
.bg-sky + .bg-tip{ margin:9px 0 0 }
.bg-cells{ display:grid; grid-template-columns:repeat(auto-fill,minmax(92px,1fr)); gap:10px; margin:14px 0 4px }
.bg-cell{ display:flex; flex-direction:column; align-items:center; gap:7px; padding:8px 6px; cursor:pointer; font:inherit;
  border:1px solid var(--line); border-radius:var(--r-s); color:inherit;
  background:color-mix(in srgb,var(--paper-lo) 50%, transparent);
  transition:transform var(--t) var(--ease-spring), border-color var(--t) }
.bg-cell:hover{ transform:translateY(-2px); border-color:var(--mist) }
.bg-cell.on{ border-color:var(--accent); box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 26%, transparent) }
.bg-dot{ width:100%; height:32px; border-radius:var(--r-s); box-shadow:inset 0 0 0 1px rgba(20,45,70,.14) }
.bg-cell small{ font-size:11.5px; color:var(--muted); letter-spacing:.04em }
.bg-thumbs{ display:grid; grid-template-columns:repeat(auto-fill,minmax(62px,1fr)); gap:8px;
  margin:14px 0 4px; max-height:290px; overflow:auto; padding-right:2px }
.bg-thumb{ padding:0; line-height:0; cursor:pointer; overflow:hidden; border-radius:var(--r-s);
  border:1px solid var(--line); background:none;
  transition:transform var(--t) var(--ease-spring), border-color var(--t) }
.bg-thumb img{ width:100%; height:54px; object-fit:cover; }
.bg-thumb:hover{ transform:translateY(-2px) }
.bg-thumb.on{ border-color:var(--accent); box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 26%, transparent) }
.bg-tip{ margin:10px 0 0; font-size:11.5px; color:var(--muted); line-height:1.75 }
.bg-tip code{ background:var(--paper-lo); padding:1px 5px; border-radius:4px }
.bg-sep{ height:1px; margin:16px 0; background:repeating-linear-gradient(90deg,var(--line-dash) 0 6px,transparent 6px 12px) }
/* 浮层透明度那一条：跟上面几行一个宽度对齐，滑杆占满剩下的一条 */
.bg-veil{ display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:10px; align-items:center; margin-bottom:8px }
.bg-veil label{ font-size:12.5px; font-weight:700; white-space:nowrap }
.bg-veil b{ font-family:var(--font-mono); font-size:12px; color:var(--accent); min-width:38px; text-align:right }
.bg-veil .dim{ grid-column:1 / -1 }
.bg-veil input[type=range]{ width:100%; height:18px; accent-color:var(--accent); cursor:pointer }

/* ---------- 常驻播放器（player.js）：可以拖到任何地方的一张卡片 ---------- */
/* --veil 是「▦ 背景」面板里那条浮层透明度反过来算出来的实度（sky.js 在载入时写到 :root 上）。
   底色按它掺透明，字和圆盘不跟着淡 —— 淡了就读不掉了。 */
.dock{ position:fixed; left:18px; bottom:18px; z-index:46; width:min(288px,calc(100vw - 92px));
  border-radius:var(--r-m); border:1px solid var(--paper-edge);
  background:linear-gradient(178deg,
    color-mix(in srgb,var(--paper-hi) calc(var(--veil,1) * 100%), transparent),
    color-mix(in srgb,var(--paper-lo) calc(var(--veil,1) * 100%), transparent));
  box-shadow:var(--shadow-l), inset 0 1px 0 var(--hair); }
.dock[data-state="fold"]{ width:auto; border:none; background:none; box-shadow:none }
.dock.is-drag{ box-shadow:var(--shadow-lift); cursor:grabbing }
/* 拖的时候别让卡片里的按钮跟着亮 —— 但抓手本身不能关事件，否则指针捕获会丢 */
.dock.is-drag .dk-body, .dock.is-drag .dk-list{ pointer-events:none }        /* 拖的时候别顺手点到下面的曲目行 */
.dk-head{ display:grid; grid-template-columns:auto minmax(0,1fr) auto auto; gap:8px; align-items:center;
  padding:10px 12px 9px; border-bottom:var(--rule-seam); cursor:grab; touch-action:none;
  user-select:none; -webkit-user-select:none }
.dk-head:active{ cursor:grabbing }
.dk-head b{ font-size:13px; font-weight:700; letter-spacing:.02em }
.dk-head-i{ width:16px; height:16px; color:var(--accent); display:block; opacity:.9 }
.dk-head-i svg{ width:100%; height:100% }
.dk-head-n{ font-family:var(--font-mono); font-size:10.5px; color:var(--pencil) }
.dk-fold{ border:1px solid var(--line); border-radius:999px; background:color-mix(in srgb,var(--paper-lo) 55%, transparent);
  padding:2px 9px; cursor:pointer; font:inherit; font-size:11px; letter-spacing:.04em; color:var(--muted); white-space:nowrap }
.dk-fold:hover{ color:var(--accent); border-color:var(--mist) }
.dk-body{ padding:14px 14px 10px; text-align:center }

/* 圆盘：盘面是她自己存的那张画（player.disc），转不转跟着真放没放声走 */
.dk-disc{ position:relative; display:block; width:104px; height:104px; margin:0 auto 12px; padding:0;
  border-radius:50%; border:1px solid var(--paper-edge); cursor:pointer; overflow:hidden;
  background:radial-gradient(circle at 50% 50%, var(--paper-hi), var(--paper-lo));
  box-shadow:var(--shadow-m), inset 0 0 0 4px color-mix(in srgb,var(--paper-hi) 70%, transparent);
  transition:box-shadow .22s ease }
.dk-disc[disabled]{ cursor:default; opacity:.55 }
.dk-disc img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block }
.dk-disc .dk-vinyl, .dkp-disc .dk-vinyl{ position:absolute; inset:0; color:var(--accent); opacity:.6; display:block }
.dk-disc .dk-vinyl svg, .dkp-disc .dk-vinyl svg{ width:100%; height:100% }
.dock[data-state="play"] .dk-disc img,
.dock[data-state="play"] .dk-disc .dk-vinyl svg,
.dock[data-state="play"] .dkp-disc .dk-vinyl svg{ animation:dkSpin 14s linear infinite }
.dk-hub{ position:absolute; left:50%; top:50%; width:13px; height:13px; margin:-6.5px 0 0 -6.5px;
  border-radius:50%; background:var(--ink); opacity:.72; box-shadow:0 0 0 3px color-mix(in srgb,var(--paper-hi) 55%, transparent) }
.dk-tri{ position:absolute; right:9px; bottom:9px; width:26px; height:26px; display:grid; place-items:center;
  border-radius:50%; color:var(--accent); background:color-mix(in srgb,var(--paper-hi) 88%, transparent);
  box-shadow:0 1px 4px rgba(20,40,60,.18); transition:transform var(--t) var(--ease-spring) }
.dk-disc:hover .dk-tri{ transform:scale(1.1) }
.dk-tri svg{ width:13px; height:13px }
@keyframes dkSpin{ to{ transform:rotate(360deg) } }

.dk-t{ font-size:14px; font-weight:700; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.dk-a{ font-size:11.5px; color:var(--muted); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
/* 进度：一条细线 + 一个圆把手，拖和点都能跳；没在放的时候它不走 */
.dk-run{ display:grid; grid-template-columns:34px minmax(0,1fr) 34px; gap:8px; align-items:center; margin:12px 0 2px }
.dk-bar{ position:relative; height:14px; cursor:pointer; touch-action:none }
.dk-bar::before{ content:""; position:absolute; left:0; right:0; top:6px; height:2px; border-radius:999px;
  background:color-mix(in srgb,var(--ink) 13%, transparent) }
.dk-bar i{ position:absolute; left:0; top:6px; height:2px; width:0; border-radius:999px; background:var(--accent) }
.dk-bar b{ position:absolute; left:0; top:2px; width:10px; height:10px; margin-left:-5px; border-radius:50%;
  background:var(--paper-hi); border:1.5px solid var(--accent); box-shadow:0 1px 3px rgba(20,40,60,.2) }
.dk-time{ font-family:var(--font-mono); font-size:10.5px; color:var(--muted); text-align:center }
.dk-hint{ font-size:11px; color:var(--pencil); line-height:1.65; text-align:left }
.dk-hint code{ background:var(--paper-lo); padding:0 4px; border-radius:3px }
.dk-out{ display:inline-block; margin-top:8px; font-size:12px; padding:3px 12px; border-radius:999px;
  border:1px solid var(--mist); color:var(--accent) }
.dk-ctl{ display:flex; gap:10px; align-items:center; justify-content:center; margin-top:8px }
.dk-btn{ width:28px; height:28px; border-radius:50%; display:grid; place-items:center; cursor:pointer;
  border:1px solid var(--line); color:var(--ink-soft);
  background:color-mix(in srgb,var(--paper-lo) 60%, transparent);
  transition:color var(--t) var(--ease-ink), border-color var(--t), transform var(--t) var(--ease-spring) }
.dk-btn svg{ width:14px; height:14px }
.dk-btn:hover{ color:var(--accent); border-color:var(--mist); transform:translateY(-1px) }
.dk-main{ width:38px; height:38px; color:var(--accent); border-color:var(--mist) }
.dk-main svg{ width:16px; height:16px }
.dk-list{ display:flex; flex-direction:column; gap:1px; padding:0 9px 9px; max-height:186px; overflow:auto;
  /* 头顶那道缝由 .dk-head 的下边线管着：这里再画一道就成两条线挨在一起了 */
  margin-top:2px }
.dk-tr{ display:grid; grid-template-columns:18px minmax(0,1fr) auto; gap:8px; align-items:center; text-align:left;
  cursor:pointer; padding:5px 8px; border:none; border-radius:var(--r-s); background:none; font:inherit;
  font-size:12.5px; color:var(--ink-soft); transition:background var(--t-fast) }
.dk-tr:hover{ background:color-mix(in srgb,var(--paper-lo) 72%, transparent) }
.dk-tr.on{ color:var(--accent); font-weight:700 }
.dk-tr-n{ font-family:var(--font-mono); font-size:10.5px; color:var(--pencil) }
.dk-tr.on .dk-tr-n{ color:var(--accent) }
.dk-tr-t{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.dk-tr-t i{ font-style:normal; color:var(--muted); font-weight:400; margin-left:6px; font-size:11.5px }
.dk-tr-tag{ font-size:10.5px; color:var(--pencil); white-space:nowrap }
/* 收起之后那颗小胶囊：以前只有一行小字，铺在她那张深色的水上图上几乎看不出来。
   加了盘面缩略图、重投影和一道描边，在放的时候右边那个点亮着。 */
.dk-pill{ position:relative; display:flex; align-items:center; gap:8px; cursor:pointer;
  max-width:calc(100vw - 36px); padding:7px 9px 7px 7px; border-radius:999px;
  border:1px solid var(--paper-edge);
  background:linear-gradient(178deg,
    color-mix(in srgb,var(--paper-hi) calc(var(--veil,1) * 100%), transparent),
    color-mix(in srgb,var(--paper-lo) calc(var(--veil,1) * 100%), transparent));
  box-shadow:var(--shadow-l), inset 0 1px 0 var(--hair);
  font-size:12.5px; color:var(--ink-soft); touch-action:none; user-select:none; -webkit-user-select:none }
.dock.is-drag .dk-pill{ box-shadow:var(--shadow-lift) }
.dkp-disc{ position:relative; flex:none; width:28px; height:28px; border-radius:50%; overflow:hidden;
  background:radial-gradient(circle at 50% 50%, var(--paper-hi), var(--paper-lo));
  box-shadow:inset 0 0 0 1px var(--paper-edge) }
.dkp-disc img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block }
.dkp-t{ min-width:0; max-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:700 }
.dkp-dot{ flex:none; width:7px; height:7px; border-radius:50%; background:var(--line-dash) }
.dkp-dot.on{ background:var(--accent); animation:dkPulse 1.6s ease-in-out infinite }
@keyframes dkPulse{ 50%{ opacity:.35 } }
.dkp-x{ flex:none; width:18px; height:18px; border:none; border-radius:50%; background:none; cursor:pointer;
  font-size:14px; line-height:1; color:var(--pencil) }
.dkp-x:hover{ color:var(--accent) }
@media (max-width:720px){
  /* 展开的播放器以前在手机上撑到 463px —— 三分之一屏被一张卡片占住。
     圆盘本来就是装饰（点它等于点播放），缩到 64 不损失任何操作；
     曲目列表留 3 行半，要往下翻它自己滚。 */
  .dock{ left:12px; bottom:12px; width:min(252px,calc(100vw - 76px)) }
  .dk-body{ padding:11px 12px 8px }
  .dk-list{ max-height:76px }
  .dk-disc{ width:64px; height:64px; margin-bottom:7px }
  .dk-disc .dk-tri{ width:20px; height:20px; right:5px; bottom:5px }
  .dk-disc .dk-tri svg{ width:11px; height:11px }
  .dk-disc .dk-hub{ width:11px; height:11px; margin:-5.5px 0 0 -5.5px }
}

/* ---------- 歌词：卡片上的一行 + 点开的那一屏（player.js / content/lyrics.js） ---------- */
/* 词」那个小章是入口：这一首有 .lrc 才出现，没有就整行都不摆，不写「暂无歌词」占位置 */
.dk-ly{ display:flex; align-items:center; gap:7px; width:100%; margin:10px 0 0; padding:4px 8px 4px 5px;
  border:1px dashed var(--line-dash); border-radius:999px; background:none; cursor:pointer; text-align:left;
  transition:border-color var(--t) var(--ease-ink), background var(--t) }
.dk-ly:hover{ border-color:var(--mist); background:color-mix(in srgb,var(--paper-lo) 60%, transparent) }
.dk-ly-b{ flex:none; width:17px; height:17px; display:grid; place-items:center; border-radius:var(--r-s);
  background:color-mix(in srgb,var(--iris) 14%, transparent); color:var(--accent); font-size:10.5px; font-weight:700 }
.dk-ly-t{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:11.5px; line-height:17px; color:var(--ink-soft) }
.dk-ly-x{ flex:none; font-size:10px; color:var(--pencil) }

/* 那一屏：中间那一句浮到正中心，上下各留半屏空白，第一句也够升到中间 */
.ly-dialog{ --lyh:min(52vh,420px); overflow:hidden; padding:16px 16px 0; max-width:min(640px,94vw) }
.ly-head{ display:flex; align-items:baseline; gap:10px; padding:0 4px 10px }
.ly-head b{ font-size:15.5px; font-weight:700; letter-spacing:.02em }
.ly-head span{ font-size:11.5px; color:var(--muted) }
.ly-back{ margin-left:auto; align-self:center; font-size:11.5px; white-space:nowrap;
  padding:3px 11px; border:1px solid var(--line); border-radius:999px; color:var(--muted) }
.ly-back:hover{ color:var(--accent); border-color:var(--mist) }
.ly-head .bg-close{ margin-left:0; align-self:center }
.ly-body{ position:relative; height:var(--lyh); overflow-y:auto; overscroll-behavior:contain;
  padding:calc(var(--lyh) / 2) 2px; text-align:center; scroll-behavior:auto }
.ly-line{ display:block; width:100%; margin:0; padding:8px 10px; border:none; background:none; cursor:pointer;
  font:inherit; text-align:center; color:var(--ink-soft); line-height:1.5; font-size:15.5px; opacity:.38;
  transition:opacity .3s var(--ease-ink), color .3s var(--ease-ink), transform .3s var(--ease-ink) }
.ly-line:hover{ opacity:.72 }
/* 正在唱的那一句放大用 transform，不动字号 —— 字号一变每一行的高度就跟着变，刚算好的中心位置当场作废 */
.ly-line.on{ opacity:1; color:var(--accent); font-weight:700; transform:scale(1.14) }
/* 网易云那些 .lrc 开头几行是制作名单（作曲 / 作词 / 混音…），不是歌词：小一号、不放大，别跟正文抢 */
.ly-line.ly-cr{ font-size:11.5px; line-height:1.6; opacity:.3 }
.ly-line.ly-cr.on{ transform:none; font-weight:600 }
@media (max-width:720px){
  .ly-dialog{ --lyh:46vh; padding:14px 10px 0 }
  .ly-line{ font-size:14.5px }
  .ly-line.on{ transform:scale(1.06) }
}

/* ---------- 留言板弹幕 ---------- */
/* 背景是她画集里那张 495c8ad8（天空之镜：一小辆车、一个人、一整片云）。
   挑它是因为主体都只有几个像素大，药丸压过去不挡东西；换图只改这一行 url。
   图本身亮，所以固定压一层深色 —— 三套光线都用同一层，白字在任何一张上都站得住。 */
.dm-stage{ position:relative; height:196px; margin:2px 0 10px; overflow:hidden; border-radius:var(--r-m);
  background:#1b2c3d url("../img/art/495c8ad8.jpg") no-repeat center 44%; background-size:cover;
  border:1px solid var(--paper-edge); box-shadow:var(--shadow-s) }
.dm-stage::before{ content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(180deg,rgba(12,24,36,.30),rgba(12,24,36,.52)) }
.dm-item{ position:absolute; left:0; white-space:nowrap; font-size:13px; padding:4px 13px; border-radius:999px;
  background:rgba(14,26,38,.52); border:1px solid rgba(255,255,255,.17);
  color:#eef4fa; text-shadow:0 1px 1px rgba(6,16,26,.45);
  /* 起点是这段道自己的宽（JS 量完写在 --dm-w 上），不是屏幕宽；没量到时退回屏幕宽，一样能飘 */
  transform:translate3d(var(--dm-w,100vw),0,0); animation:dmRun 22s linear infinite both; will-change:transform }
.dm-item b{ color:var(--c, #9ed0ff); font-weight:700; margin-right:8px }
.dm-place{ font-style:normal; margin-left:9px; font-size:11px; opacity:.66 }
@keyframes dmRun{ to{ transform:translate3d(-100%,0,0) } }
.dm-stage.is-off .dm-item{ animation-play-state:paused }   /* 滚出视口就停，core 那个 IntersectionObserver 负责 */
.dm-quiet{ position:absolute; inset:0; display:grid; place-items:center; font-size:12.5px; color:rgba(238,244,250,.82) }
.dm-bar{ display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-bottom:16px }

@media (max-width:720px){
  .dm-stage{ height:124px }   /* 手机上只有三条道（JS 按宽度挑道数），框子跟着收 */
  .gb-item{ grid-template-columns:32px minmax(0,1fr); gap:9px; padding:12px 13px }
  .gb-av{ width:32px; height:32px; font-size:13px }
  .gb-top{ gap:7px }
}

/* =========================================================
   触屏：这种设备上根本不存在「悬停」
   照片的删除键、愿望的 ×、画集的出处以前只靠 :hover 显形，
   手指没有 hover —— 手机上编辑模式就变成了「删不掉照片、划不掉愿望、看不到出处」。
   和上面 .av-hint 那条是同一个毛病，一起在这里收掉，另外把命中区撑到指头大小。
   ========================================================= */
@media (hover:none){
  .photo .photo-x{ opacity:.9; display:grid; place-items:center; width:34px; height:34px; top:8px; right:8px; font-size:17px }
  .wish .wish-del{ opacity:.7; padding:9px 13px; font-size:17px }
  .gb-del{ opacity:.8; padding:8px 12px }
  .art-item .art-cred{ opacity:.92 }
  /* 命中区：鼠标能点中 9px 的点、28px 的键，指头不行。字号一律不动。 */
  .id-link{ height:40px; min-width:40px }
  /* 收藏夹那张卡上「池泛的小窝」就是一个行内链接：20px 高的手指印。
     负 margin 抵掉补出来的 padding，字的位置一点没挪，点起来宽裕一圈。 */
  .jar-card a{ display:inline-flex; align-items:center; min-height:40px; padding:0 8px; margin:0 -8px }
  .nb-nav{ width:38px; height:52px }
  /* 翻页点：9px 的小圆点按不到，但直接把宽高撑到 32 就又变成一颗大痘。
     外壳只负责接手指，看得见的点交给 ::before 画在正中。 */
  .nb-dots{ gap:3px }
  .nb-dot{ position:relative; width:32px; height:32px; padding:0; border:none; background:none }
  .nb-dot::before{ content:""; position:absolute; inset:11px; border-radius:50%;
    border:1px solid var(--line); background:color-mix(in srgb,var(--paper-hi) 70%, transparent);
    transition:background var(--t-fast), border-color var(--t-fast), transform var(--t) var(--ease-spring) }
  .nb-dot:hover::before{ transform:scale(1.3) }
  .nb-dot.on::before{ background:var(--accent); border-color:var(--accent) }
  .dk-btn{ width:36px; height:36px } .dk-btn svg{ width:16px; height:16px }
  .dk-main{ width:40px; height:40px } .dk-main svg{ width:18px; height:18px }
  .dk-tr{ padding:11px 8px }
  /* 「收起」「词」这两条是胶囊形的，把 padding 加上去整张卡就鼓一圈，而展开的播放器
     在手机上本来就把下半屏占满了 —— 同样用透明的 ::before 往外讨一圈命中区，图上不动。 */
  .dk-fold, .dk-ly{ position:relative }
  .dk-fold::before{ content:""; position:absolute; inset:-6px }
  .dk-ly::before{ content:""; position:absolute; inset:-5px }
  .hero-shuffle{ width:40px; height:40px; margin-top:-20px }
  .hero-swap{ padding:11px 14px }
  /* 勾选框、胶囊上那个 × 这种「图形本来就这么小」的控件，撑大盒子就变丑陋。
     ::before 那一圈透明的扩展命中区才是正解：图上多一像素没有，手指多讨到十来像素。 */
  .wish-box, .dkp-x{ position:relative }
  .wish-box::before{ content:""; position:absolute; inset:-11px }
  .dkp-x::before{ content:""; position:absolute; inset:-8px }
  /* 心气色带：16 列压在窄屏上，一格只有 14px 宽 —— 宽度是「一年看得全」换来的，动不得；
     先把高度垫到 28，竖向至少点得住。横向点到隔壁一天也只是日期差一格，看得出、改得回。 */
  .m-cell{ height:28px }
  /* 打卡那 56 格更狠：一格 12×12，格与格只有 3 像素的缝，整排还得横向滚 —— 手指点上去
     多半落在缝里，等于没点。同样不动图形，用透明的 ::before 向四周各讨 6 像素（量过：
     缝里那几个点从前打在容器上，现在每一处都落得进某一格）。差一天看得出、也改得回。 */
  .hm-cell{ position:relative }
  .hm-cell::before{ content:""; position:absolute; inset:-6px }
  /* 404 那一张「挑一页去」的格子： desktop 两列 22px 一行没事儿，手指就点不准了 */
  .place-grid .place{ min-height:40px }
  /* 「在循环的歌」那一行：播放键住在 26px 的网格里，撑大按键就要同时撑大那一列 */
  .np-row{ grid-template-columns:36px minmax(0,1fr) auto }
  .np-play{ width:36px; height:36px; display:grid; place-items:center }
}

/* =========================================================
   笔记房：柱子当目录，时间当下楼梯
   ========================================================= */
/* 首屏那排月度柱：按月写作的量，点一根就只看那个月 */
.kb-bar-row{ display:flex; align-items:stretch; gap:6px; height:132px; padding:4px 0 2px; overflow-x:auto; overflow-y:hidden; }
.kb-bar{ flex:1 1 0; min-width:26px; display:flex; flex-direction:column; justify-content:flex-end; align-items:center;
  gap:5px; padding:0; background:none; border:none; cursor:pointer; color:var(--muted); border-radius:var(--r-s) }
.kb-bar-n{ font-family:var(--font-serif); font-size:11px; line-height:1; font-variant-numeric:tabular-nums; opacity:.72; }
.kb-bar-fill{ flex:0 1 auto; width:100%; max-width:34px; min-height:4px; border-radius:5px 5px 2px 2px;
  background:linear-gradient(180deg,color-mix(in srgb,var(--mist) 92%,transparent),color-mix(in srgb,var(--indigo) 58%,transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--indigo) 26%,transparent);
  transition:background var(--t) var(--ease-ink), box-shadow var(--t) var(--ease-ink) }
.kb-bar-x{ font-size:10.5px; line-height:1; font-variant-numeric:tabular-nums; letter-spacing:.02em }
.kb-bar:hover .kb-bar-fill{ background:linear-gradient(180deg,var(--mist),var(--indigo)) }
.kb-bar:hover .kb-bar-n,.kb-bar:hover .kb-bar-x{ color:var(--ink); opacity:1 }
/* 选中那根换成沙色：一整排水蓝里挑出来说话的柱子，比加边框更省事也更好认 */
.kb-bar.on .kb-bar-fill{ background:linear-gradient(180deg,color-mix(in srgb,var(--sand) 72%,#fff),var(--sand));
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--sand) 55%,transparent) }
.kb-bar.on .kb-bar-n,.kb-bar.on .kb-bar-x{ color:var(--sand); font-weight:700; opacity:1 }

.kb-tools{ display:flex; align-items:center; gap:10px }
.kb-q{ flex:1 1 auto; min-width:0 }
.kb-count{ margin-left:auto; font-size:12.5px; color:var(--muted); white-space:nowrap; font-variant-numeric:tabular-nums }
.kb-err{ font-size:13px; color:var(--seal); padding:8px 12px; border-radius:var(--r-s);
  background:color-mix(in srgb,var(--rose) 12%,transparent); border:1px dashed color-mix(in srgb,var(--seal) 42%,transparent) }
.kb-loading{ font-family:var(--font-hand); font-size:14px; color:var(--muted); letter-spacing:.1em }

/* 列表：左边一列月份，右边一篇篇往下走 */
.kb-list{ display:flex; flex-direction:column; gap:24px }
.kb-year-h{ display:flex; align-items:baseline; gap:10px; font-family:var(--font-serif); font-size:17px;
  letter-spacing:.14em; color:var(--ink-soft); padding-bottom:7px; margin-bottom:8px; border-bottom:1px solid var(--line) }
.kb-year-h::after{ content:""; flex:1; height:0; border-top:1px dashed var(--line-dash) }
.kb-month{ position:relative; display:grid; grid-template-columns:56px minmax(0,1fr); gap:0 16px; align-items:start }
.kb-month::before{ content:""; position:absolute; left:60px; top:2px; bottom:6px; border-left:1px dashed var(--line-dash) }
.kb-month-h{ grid-column:1; text-align:right; padding-top:11px; font-family:var(--font-serif); font-size:13.5px;
  letter-spacing:.06em; color:var(--accent); font-variant-numeric:tabular-nums }
.kb-item{ grid-column:2; padding:9px 12px; border-radius:var(--r-s); cursor:pointer;
  /* 和 .post / .card 同一档：底色听「▦ 背景」那条滑杆（--veil）掺透明，字不跟着淡。
     之前这块是纯透明的，滑杆在笔记房拉着没反应，字直接压在底图上读不掉。 */
  background-image:linear-gradient(178deg,
    color-mix(in srgb,var(--paper-hi) calc(var(--veil,1) * 100%), transparent),
    color-mix(in srgb,var(--paper-lo) calc(var(--veil,1) * 100%), transparent));
  background-color:transparent;
  border:1px solid var(--paper-edge); transition:background-color var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast) }
.kb-item:hover{ background-color:color-mix(in srgb,var(--paper-hi) 30%,transparent); border-color:var(--line); box-shadow:inset 2px 0 0 var(--accent) }
.kb-item-t{ font-family:var(--font-serif); font-size:15.5px; line-height:1.6; letter-spacing:.03em; transition:color var(--t-fast) }
.kb-item:hover .kb-item-t{ color:var(--accent) }
.kb-item-s{ font-size:13px; line-height:1.75; color:var(--muted); margin:3px 0 5px;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden }
.kb-item-s:empty{ display:none }
.kb-item-m{ display:flex; flex-wrap:wrap; align-items:center; gap:5px 9px; font-size:11px;
  color:var(--muted); font-variant-numeric:tabular-nums }
.kb-item-m .dot{ width:3px; height:3px; border-radius:50%; background:var(--line-dash); display:inline-block }
.kb-item-m .sb-tag{ font-size:11px; padding:0 7px }

.kb-pager{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  margin-top:4px; padding-top:14px; border-top:var(--rule-seam) }
.kb-pager-n{ font-family:var(--font-serif); font-size:13px; color:var(--muted); letter-spacing:.08em; font-variant-numeric:tabular-nums }

/* 侧栏：分类 / 标签 / 归档 —— 计数写在胶囊里，点一下就换一批 */
.kb-pick{ display:flex; flex-wrap:wrap; gap:7px }
.kb-pick .chip i{ font-style:normal; opacity:.55; font-size:11px; margin-left:5px; font-variant-numeric:tabular-nums }
.kb-facts{ display:flex; flex-direction:column; gap:8px; font-size:13.5px; color:var(--ink-soft) }
.kb-facts li{ position:relative; padding-left:14px }
.kb-facts li::before{ content:""; position:absolute; left:0; top:11px; width:5px; height:5px; border-radius:50%; background:var(--line-dash) }
.kb-facts b{ font-family:var(--font-serif); font-size:16px; color:var(--accent); margin-right:3px; font-variant-numeric:tabular-nums }
.kb-facts-note{ padding-left:0 !important; margin-top:4px; font-size:12px; line-height:1.75; color:var(--muted) }
.kb-facts-note::before{ display:none }
.kb-facts-note code{ font-family:var(--font-mono); font-size:11.5px; color:var(--ink-soft);
  background:var(--paper-lo); border:1px solid var(--line); border-radius:var(--r-xs); padding:1px 5px; word-break:break-all }

/* ---------------- 单篇 ---------------- */
.layout.kb-read{ grid-template-columns:292px minmax(0,1fr) }
/* 笔记比手帐宽：42em 那条读书栏装不下一张 MySQL 参数表 */
.kb-body{ max-width:50em }
/* 首段常常是「一句话解释」，不是小说的开头 —— 下沉首字在这儿读着怪 */
.kb-body > p:first-child::first-letter{ float:none; font-size:inherit; line-height:inherit; padding:0; color:inherit; font-weight:inherit }
.kb-hero{ margin:6px 0 20px; text-align:center; cursor:zoom-in }
.kb-hero img{ display:inline-block; width:auto; height:auto; max-width:100%; max-height:min(46vh,360px);
  border-radius:var(--r-s); border:1px solid var(--paper-edge); box-shadow:var(--shadow-m); transition:box-shadow .22s ease }
.kb-hero:hover img{ box-shadow:var(--shadow-l) }
.kb-hero figcaption{ font-family:var(--font-hand); font-size:12.5px; color:var(--muted); margin-top:9px; letter-spacing:.04em }
.kb-hero figcaption i{ font-style:normal; opacity:.6; margin-left:9px }
.kb-meta{ display:flex; flex-wrap:wrap; align-items:center; gap:5px 13px; margin-top:11px;
  font-size:12.5px; color:var(--muted); letter-spacing:.04em; font-variant-numeric:tabular-nums }
.kb-meta span{ display:inline-flex; align-items:center }
.kb-series-tag{ padding:1px 9px; border-radius:999px; font-size:11.5px; color:var(--teal);
  background:color-mix(in srgb,var(--teal) 13%,transparent); border:1px solid color-mix(in srgb,var(--teal) 38%,transparent) }

.kb-toc ol{ display:flex; flex-direction:column; gap:1px; max-height:min(48vh,420px); overflow:auto; margin:0; padding:0;
  /* 目录这一栏不摆进度条：滚到最底下那几行自己渐渐淡掉，比一根灰杠子清楚，也不挡字 */
  scrollbar-width:none;
  -webkit-mask-image:linear-gradient(#000 calc(100% - 20px), transparent);
  mask-image:linear-gradient(#000 calc(100% - 20px), transparent); }
.kb-toc ol::-webkit-scrollbar{ display:none }
.kb-toc li.lv3{ padding-left:11px }
.kb-toc li.lv4{ padding-left:22px }
.kb-toc button{ display:block; width:100%; text-align:left; font:inherit; font-size:13px; line-height:1.5;
  color:var(--ink-soft); background:none; border:none; border-left:2px solid transparent; border-radius:0 6px 6px 0;
  padding:4px 8px; cursor:pointer; transition:color var(--t-fast), background var(--t-fast), border-color var(--t-fast) }
.kb-toc button:hover{ background:var(--paper-lo); color:var(--accent) }
.kb-toc button.on{ color:var(--accent); font-weight:700; border-left-color:var(--accent);
  background:color-mix(in srgb,var(--mist) 20%,transparent) }
.kb-toc.is-fold > details > summary{ cursor:pointer; list-style:none; font-size:12.5px; color:var(--muted); padding:2px 0 }
.kb-toc.is-fold > details > summary::-webkit-details-marker{ display:none }
.kb-toc.is-fold > details > summary::before{ content:"▸"; display:inline-block; margin-right:7px; transition:transform .2s var(--ease-ink) }
.kb-toc.is-fold > details[open] > summary::before{ transform:rotate(90deg) }

.kb-ref-h{ font-family:var(--font-serif); font-size:13.5px; letter-spacing:.1em; color:var(--accent); margin:15px 0 4px }
.card > .kb-ref-h:first-child{ margin-top:2px }
.kb-ref{ display:flex; flex-direction:column; gap:1px }
.kb-ref a{ display:flex; align-items:baseline; gap:8px; padding:5px 9px; border-radius:var(--r-s);
  font-size:13.5px; color:var(--ink-soft); transition:background var(--t-fast), color var(--t-fast) }
.kb-ref a:hover{ background:var(--paper-lo); color:var(--accent) }
.kb-ref a i{ font-style:normal; margin-left:auto; padding-left:8px; font-size:11.5px; color:var(--muted);
  white-space:nowrap; font-variant-numeric:tabular-nums }

.kb-pair{ display:grid; grid-template-columns:1fr 1fr; gap:12px }
.kb-pair .btn{ min-width:0 }
.kb-pair-t{ display:block; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.kb-pair-r{ justify-content:flex-end }

/* 右下角：读到哪儿了 + 回顶。音乐胶囊住在左下角，不打架 */
.kb-fab{ position:fixed; right:20px; bottom:24px; z-index:44; display:flex; flex-direction:column; align-items:center; gap:9px }
.kb-ring{ position:relative; width:44px; height:44px; border-radius:50%; border:none; cursor:default;
  display:grid; place-items:center; box-shadow:var(--shadow-m);
  background:conic-gradient(var(--accent) calc(var(--p,0) * 1turn), color-mix(in srgb,var(--paper-edge) 62%,transparent) 0) }
.kb-ring::before{ content:""; position:absolute; inset:3px; border-radius:50%;
  background:color-mix(in srgb,var(--paper-hi) 94%,transparent) }
.kb-ring span{ position:relative; font-family:var(--font-serif); font-size:10.5px; color:var(--ink-soft); font-variant-numeric:tabular-nums }
.kb-top{ width:44px; height:44px; border-radius:50%; display:grid; place-items:center; cursor:pointer; font-size:15px;
  color:var(--ink-soft); border:1px solid var(--paper-edge); box-shadow:var(--shadow-m);
  background:color-mix(in srgb,var(--paper-hi) 92%,transparent);
  transition:transform var(--t) var(--ease-ink), color var(--t), border-color var(--t) }
.kb-top:hover{ transform:translateY(-2px); color:var(--accent); border-color:var(--mist) }

@media (max-width:720px){
  .kb-bar-row{ height:112px }
  .kb-bar{ min-width:22px }
  .kb-month{ grid-template-columns:minmax(0,1fr); gap:0 }
  .kb-month::before{ display:none }
  .kb-month-h{ grid-column:1; text-align:left; padding:2px 0 4px }
  .kb-item{ grid-column:1; padding:8px 6px }
  .layout.kb-read{ grid-template-columns:minmax(0,1fr) }
  .kb-toc ol{ max-height:none }
  .kb-pair{ grid-template-columns:1fr }
  .kb-pair-r{ justify-content:flex-start }
  .kb-fab{ right:12px; bottom:16px; gap:7px }
  .kb-ring,.kb-top{ width:38px; height:38px }
}
@media (hover:none){
  /* 柱子是这一页最要紧的入口，26px 的宽度按不住 —— 用透明 ::before 往外讨一圈，看得见的那截不胖 */
  .kb-bar{ position:relative }
  .kb-bar::before{ content:""; position:absolute; inset:-4px -3px }
  .kb-toc button{ padding:9px 8px }
  .kb-item{ padding:13px 12px }
  .kb-ref a{ padding:10px 9px }
}
