/*
Theme Name: Minimer
Theme URI: https://www.dogfight360.com/
Description: Dogfight360 的 Minimer 2.0 —— 完整重设计：一个背景色、发丝线与两级阴影、Signal Blue 单主色、原生深浅配色、弹簧动效（零依赖 JS）。沿用 1.x 的菜单位置 / 挂件区 / 图片尺寸命名与全部主题配置，直接覆盖旧目录即可升级。基于 Alx 的 Minimer 重构。
Author: 羽翼城 & Claude
Version: 2.4.9
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html
Text Domain: minimer
*/

/* ==========================================================================
   Tokens — one background · one surface per region · hairline + 2 shadows
   Spacing: 4 / 8 / 16 / 32 / 64 · Radius: 8 (cards) / 6 (controls)
   ========================================================================== */
:root {
  color-scheme: light;
  --bg: #F6F7F9;
  --surface: #FFFFFF;
  --line: #E3E6EB;
  --ink: #1B1E24;
  --ink-2: #5A626E;
  --primary: #2660C8;
  --primary-contrast: #FFFFFF;
  --warm: #C98A2D;
  --danger: #B4372E;
  --shadow-1: 0 1px 2px rgba(27, 30, 36, .06), 0 2px 8px rgba(27, 30, 36, .06);
  --shadow-2: 0 1px 2px rgba(27, 30, 36, .08), 0 8px 24px rgba(27, 30, 36, .12);
  --r-lg: 8px;
  --r-md: 6px;
  --font-sans: "Inter", -apple-system, system-ui, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, "Cascadia Mono", Consolas, Menlo, monospace;
  --ease-micro: cubic-bezier(.22, 1, .36, 1);
  /* spring(stiffness 600, damping 25): 15.5% overshoot @149ms, settled by 500ms */
  --spring-pop: cubic-bezier(.3, 1.36, .5, 1);
  --header-h: 64px;
}
@supports (animation-timing-function: linear(0, 1)) {
  :root {
    --spring-pop: linear(0, 0.082 3.6%, 0.273 7.1%, 0.506 10.7%, 0.73 14.3%, 0.915 17.9%, 1.046 21.4%, 1.123 25%, 1.153 28.6%, 1.149 32.1%, 1.124 35.7%, 1.089 39.3%, 1.053 42.9%, 1.022 46.4%, 0.999 50%, 0.984 53.6%, 0.977 57.1%, 0.976 60.7%, 0.979 64.3%, 0.984 67.9%, 0.99 71.4%, 0.995 75%, 0.999 78.6%, 1.002 82.1%, 1.003 85.7%, 1.004 89.3%, 1.003 92.9%, 1.003 96.4%, 1);
  }
}
html[data-theme="dark"] {
  color-scheme: dark;
  --bg: #15171B;
  --surface: #1D2026;
  --line: #2A2E36;
  --ink: #E9EBEF;
  --ink-2: #9AA3B0;
  --primary: #8FB4F2;
  --primary-contrast: #10131A;
  --warm: #D9A85C;
  --danger: #E08A83;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .35), 0 2px 8px rgba(0, 0, 0, .30);
  --shadow-2: 0 1px 2px rgba(0, 0, 0, .40), 0 8px 24px rgba(0, 0, 0, .45);
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme]) {
    color-scheme: dark;
    --bg: #15171B; --surface: #1D2026; --line: #2A2E36;
    --ink: #E9EBEF; --ink-2: #9AA3B0;
    --primary: #8FB4F2; --primary-contrast: #10131A;
    --warm: #D9A85C; --danger: #E08A83;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .35), 0 2px 8px rgba(0, 0, 0, .30);
    --shadow-2: 0 1px 2px rgba(0, 0, 0, .40), 0 8px 24px rgba(0, 0, 0, .45);
  }
}

@font-face {
  font-family: "Inter";
  src: url("assets/fonts/Inter-var-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   Base
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.7;
  word-wrap: break-word;
}
img { max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, h3, h4, h5, h6, p, ul, ol, figure, blockquote, fieldset { margin: 0; padding: 0; }
embed, iframe, object, video { max-width: 100%; }
::selection { background: color-mix(in srgb, var(--primary) 24%, transparent); }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }

.screen-reader-text {
  clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%);
  position: absolute !important; width: 1px; height: 1px; overflow: hidden; word-wrap: normal !important;
}
.skip-link {
  position: absolute; left: 16px; top: 16px; z-index: 200;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 8px 16px; font-weight: 600; box-shadow: var(--shadow-2);
  transform: translateY(-80px);                 /* park above the viewport via transform, not top */
  transition: transform .2s var(--ease-micro);
}
.skip-link:focus-visible { transform: none; clip: auto; clip-path: none; width: auto; height: auto; }

.shell { max-width: 1128px; margin-inline: auto; padding-inline: 32px; }
.meta, time, .chip { font-variant-numeric: tabular-nums; }
.mask-icon {
  display: inline-block; width: 17px; height: 17px;
  background: currentColor;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.icon-steam       { -webkit-mask-image: url(assets/img/steam.svg); mask-image: url(assets/img/steam.svg); }
.icon-xbox        { -webkit-mask-image: url(assets/img/xbox.svg); mask-image: url(assets/img/xbox.svg); }
.icon-discord     { -webkit-mask-image: url(assets/img/discord.svg); mask-image: url(assets/img/discord.svg); }
.icon-xiaohongshu { -webkit-mask-image: url(assets/img/xiaohongshu.svg); mask-image: url(assets/img/xiaohongshu.svg); }
.icon-mail        { -webkit-mask-image: url(assets/img/mail.svg); mask-image: url(assets/img/mail.svg); }
.icon-link        { -webkit-mask-image: url(assets/img/link.svg); mask-image: url(assets/img/link.svg); }
.icon-win         { -webkit-mask-image: url(assets/img/win.svg); mask-image: url(assets/img/win.svg); }
.icon-mac         { -webkit-mask-image: url(assets/img/mac.svg); mask-image: url(assets/img/mac.svg); }
.icon-linux       { -webkit-mask-image: url(assets/img/linux.svg); mask-image: url(assets/img/linux.svg); }

/* ==========================================================================
   Header · nav · search · theme toggle · burger
   ========================================================================== */
.site-header { position: sticky; top: 0; z-index: 100; background: var(--bg); will-change: transform; }
.site-header::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  box-shadow: 0 1px 0 var(--line), var(--shadow-1);
  opacity: 0;
  transition: opacity .2s var(--ease-micro);
}
.site-header.is-stuck::after { opacity: 1; }
.header-bar { display: flex; align-items: center; gap: 32px; height: var(--header-h); }

.brand { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.brand .site-title { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -.01em; line-height: 1; }
.brand .site-title a { color: var(--ink); }
.brand .custom-logo, .brand img { display: block; max-height: 32px; width: auto; }
.brand-desc { font-size: 13px; color: var(--ink-2); white-space: nowrap; }

.header-nav { margin-left: auto; min-width: 0; }
.header-nav > ul { display: flex; align-items: center; gap: 8px; list-style: none; }
.nav-item { position: relative; }
.nav-link {
  display: flex; align-items: center; gap: 4px;
  padding: 8px; border-radius: var(--r-md);
  font-size: 15px; color: var(--ink-2); white-space: nowrap;
  transition: color .15s var(--ease-micro), background-color .15s var(--ease-micro);
}
.nav-link:hover { color: var(--ink); }
.nav-link[aria-current="page"],
.current-menu-item > .nav-link,
.current-menu-ancestor > .nav-link { color: var(--ink); font-weight: 600; }
.nav-link .chev { transition: transform .18s var(--ease-micro); flex-shrink: 0; }
.nav-item.open > .nav-link { color: var(--ink); }
.nav-item.open > .nav-link .chev { transform: rotate(180deg); }

.dropdown {
  position: absolute; top: calc(100% + 8px); left: -8px; z-index: 60;
  min-width: 224px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  padding: 4px;                          /* concentric: item r = 8 − 4 = 4 */
  opacity: 0;
  transform: translateY(6px) scale(.98);
  transform-origin: 24px top;
  pointer-events: none;
  transition: opacity .12s var(--ease-micro), transform .12s var(--ease-micro);
}
.nav-item:last-child .dropdown { left: auto; right: -8px; transform-origin: calc(100% - 24px) top; }
.nav-item.open > .dropdown { opacity: 1; transform: none; pointer-events: auto; transition-duration: .18s; }
.dropdown a {
  display: block; padding: 8px 12px; border-radius: 4px;
  font-size: 15px; color: var(--ink);
  transition: background-color .15s var(--ease-micro);
}
.dropdown a:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
.dropdown .depth-2 { padding-left: 28px; font-size: 14px; color: var(--ink-2); }

.header-actions { display: flex; align-items: center; gap: 4px; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--r-md);
  color: var(--ink); position: relative; flex-shrink: 0;
  transition: background-color .15s var(--ease-micro), transform .15s var(--ease-micro);
}
.icon-btn:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
.icon-btn:active { transform: scale(.94); }
.icon-btn svg { width: 20px; height: 20px; }

/* resting states double as the no-JS fallback; app.js drives the morph with
   a short interruptible ease-out tween via inline styles (immune to the
   .vt-theme freeze). will-change keeps both 20px icons on their own layers:
   the tween costs zero paint, even while a reveal is in flight. */
.theme-toggle .sun, .theme-toggle .moon {
  position: absolute;
  will-change: transform, opacity;
}
html[data-theme="dark"] .theme-toggle .sun  { opacity: 0; transform: rotate(-90deg) scale(.58); }
html[data-theme="dark"] .theme-toggle .moon { opacity: 1; transform: none; }
html:not([data-theme="dark"]) .theme-toggle .sun  { opacity: 1; transform: none; }
html:not([data-theme="dark"]) .theme-toggle .moon { opacity: 0; transform: rotate(90deg) scale(.58); }

.search-wrap { position: relative; }
.search-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  width: 320px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  padding: 8px;
  display: none;
  opacity: 0;
}
.search-pop .hint { margin: 8px 4px 0; font-size: 13px; color: var(--ink-2); }

/* search form (shared: popover, 404, search page, widget) */
.searchform { position: relative; }
.searchform input[type="search"], .searchform input[type="text"] {
  width: 100%; height: 40px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 8px 0 36px;
  font: inherit; font-size: 15px; color: var(--ink);
  transition: border-color .15s var(--ease-micro), box-shadow .15s var(--ease-micro);
}
.searchform input:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}
.searchform .search-glyph {
  position: absolute; left: 10px; top: 50%; translate: 0 -50%;
  width: 16px; height: 16px; color: var(--ink-2); pointer-events: none;
}
.searchform .search-glyph svg { display: block; width: 100%; height: 100%; }

/* core Search block widget gets the same treatment as searchform */
.wp-block-search__inside-wrapper { display: flex; gap: 8px; }
.wp-block-search__input {
  flex: 1; min-width: 0; height: 40px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 10px;
  font: inherit; font-size: 15px; color: var(--ink);
  transition: border-color .15s var(--ease-micro), box-shadow .15s var(--ease-micro);
}
.wp-block-search__input:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}
.wp-block-search__button {
  height: 40px; padding: 0 12px; flex-shrink: 0;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 4px;
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  transition: border-color .15s var(--ease-micro);
}
.wp-block-search__button:hover { border-color: color-mix(in srgb, var(--ink) 26%, var(--line)); }
.wp-block-search__label { font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 8px; display: block; }

.burger { display: none; }
.burger-icon { position: relative; width: 18px; height: 14px; }
.burger-icon span {
  position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px;
  background: currentColor;
  transition: transform .25s var(--ease-micro), opacity .2s var(--ease-micro);
}
.burger-icon span:nth-child(1) { top: 0; }
.burger-icon span:nth-child(2) { top: 6px; }
.burger-icon span:nth-child(3) { top: 12px; }
/* converge to the middle bar via translateY (transform, not top) */
.burger[aria-expanded="true"] .burger-icon span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] .burger-icon span:nth-child(2) { opacity: 0; transform: scaleX(.4); }
.burger[aria-expanded="true"] .burger-icon span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.mobile-menu {
  position: fixed; top: var(--header-h); left: 0; right: 0; z-index: 90;
  display: none;
  max-height: calc(100dvh - var(--header-h));
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-2);
  transform-origin: top;
}
.mobile-menu-inner { transform-origin: top; padding: 8px 32px 32px; }
.mm-group { padding-top: 16px; }
.mm-label { font-size: 13px; font-weight: 600; color: var(--ink-2); padding: 8px 0; }
.mm-item { display: block; padding: 8px 0; font-size: 16px; color: var(--ink); border-bottom: 1px solid var(--line); }
.mm-item:last-child { border-bottom: 0; }
.mm-item[aria-current="page"] { font-weight: 600; }
.backdrop { position: fixed; inset: var(--header-h) 0 0; z-index: 80; background: rgba(0, 0, 0, .35); display: none; opacity: 0; }

/* ==========================================================================
   Layout shells
   ========================================================================== */
.page { padding-block: 32px 64px; min-height: 60vh; }
.home-grid { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 64px; }
.article-shell { max-width: 784px; margin-inline: auto; padding-inline: 32px; }

/* ==========================================================================
   Release card (first sticky post on home)
   ========================================================================== */
.release-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: 32px;
  display: flex; align-items: center; justify-content: space-between; gap: 32px;
  margin-bottom: 64px;
}
.release-info { flex: 1; min-width: 0; }
/* optional screenshot (Customizer: sticky-image) — capsule on the left, text +
   actions stacked to its right; the title keeps its two-line breathing room */
.release-card.has-media {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  grid-template-areas: "media info" "media action";
  align-items: center;
  column-gap: 32px; row-gap: 16px;
}
.release-media {
  grid-area: media; align-self: center;
  display: block; width: 100%; aspect-ratio: 16 / 10;
  border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; background: var(--bg);
}
.release-media img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform .6s var(--ease-micro);
}
@media (hover: hover) and (pointer: fine) {
  .release-media:hover img { transform: scale(1.03); }
}
.release-card.has-media .release-info { grid-area: info; align-self: end; }
.release-card.has-media .release-action {
  grid-area: action; align-self: start;
  flex-direction: row; align-items: center; justify-content: flex-start; gap: 16px;
}
.pin-flag { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--warm); }
.pin-flag::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.release-title { font-size: 28px; font-weight: 700; letter-spacing: -.015em; line-height: 1.3; margin-top: 8px; }
.release-title a { color: var(--ink); transition: color .15s var(--ease-micro); }
.release-title a:hover { color: var(--primary); }
.release-meta { margin-top: 16px; font-size: 13px; color: var(--ink-2); display: flex; flex-wrap: wrap; gap: 8px 16px; }
.release-meta strong { color: var(--ink); font-weight: 600; }
.release-action { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; flex-shrink: 0; }
.release-action .aside-link { font-size: 13px; color: var(--ink-2); transition: color .15s var(--ease-micro); }
.release-action .aside-link:hover { color: var(--primary); }

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 16px;
  border-radius: var(--r-md);
  font-size: 15px; font-weight: 600;
  transition: background-color .15s var(--ease-micro), transform .15s var(--ease-micro), box-shadow .15s var(--ease-micro);
}
.btn svg { width: 16px; height: 16px; }
.btn-primary { background: var(--primary); color: var(--primary-contrast) !important; }
.btn-primary:hover { background: color-mix(in srgb, var(--primary) 88%, var(--ink)); box-shadow: var(--shadow-1); }
.btn-primary:active { transform: translateY(1px); box-shadow: none; }

/* ==========================================================================
   Post list (home / archive / search)
   ========================================================================== */
.list-label { font-size: 19px; font-weight: 600; margin-bottom: 16px; }
.post-list { position: relative; margin-inline: -16px; list-style: none; }
.post-list li { position: relative; border-radius: var(--r-lg); transition: background-color .15s var(--ease-micro); }
.post-list li::before {
  content: ""; position: absolute; top: 0; left: 16px; right: 16px; height: 1px;
  background: var(--line);
  transition: opacity .15s var(--ease-micro);
}
.post-list li:first-child::before { display: none; }
/* hover 表面:app.js 往列表里放一块共享底板(.list-glide),行间移动时它
   沿弹簧滑过去(FLIP:translateY+scaleY,纯 transform);初次进入在光标行
   淡入,离开列表原地淡出。无 JS / 触屏 / 减弱动效退回安静的 wash——
   行本身永不位移,悬浮即真实表面 */
.post-list:not(.has-glide) li:hover { background: var(--surface); }
.post-list li:hover::before, .post-list li:hover + li::before { opacity: 0; }
.list-glide {
  position: absolute; left: 0; top: 0; width: 100%; height: 0;
  z-index: 1; pointer-events: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  opacity: 0;
  transform-origin: 0 0;
  will-change: transform;
  transition: opacity .3s var(--ease-micro);
}
.list-glide.on { opacity: 1; transition-duration: .12s; }
.post-list a.row-link { position: relative; z-index: 2; display: block; padding: 16px; }
.post-row-title { font-size: 19px; font-weight: 600; line-height: 1.45; color: var(--ink); transition: color .15s var(--ease-micro); }
.post-row-title .pin-flag { vertical-align: 2px; margin-right: 8px; }
.post-list li:hover .post-row-title { color: var(--primary); }
.post-row-meta { margin-top: 4px; font-size: 13px; color: var(--ink-2); }
.post-row-excerpt { margin-top: 4px; font-size: 15px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.post-row-excerpt p { display: inline; margin: 0; }

/* home stream — full articles on one quiet surface, hairlines between (Customizer: home-style) */
.post-stream { display: flex; flex-direction: column; }
.post-stream .home-post { padding: 32px 0 40px; }
.post-stream .home-post:first-child { padding-top: 8px; }
.post-stream .home-post + .home-post { border-top: 1px solid var(--line); }
.home-post-title { margin: 0; font-size: 24px; font-weight: 700; line-height: 1.4; }
.home-post-title a { color: var(--ink); transition: color .15s var(--ease-micro); }
.home-post-title a:hover { color: var(--primary); }
.home-post-title .pin-flag { vertical-align: 4px; margin-right: 8px; }
.home-post-meta { margin: 6px 0 20px; font-size: 13px; color: var(--ink-2); }
.home-post-meta a { color: var(--ink-2); }
.home-post-meta a:hover { color: var(--ink); }
.home-entry.clamped {
  max-height: 360px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent 98%);
  mask-image: linear-gradient(180deg, #000 72%, transparent 98%);
}
.read-more-row { display: flex; margin-top: 16px; }
.read-more-row.align-right { justify-content: flex-end; }
/* hover = icon hand-off on one spring: the book slides out left, the arrow
   springs in from the right, and the label glides between them (the two
   margins trade 22px, so the button's outer width never moves) */
.read-more, .entry .more-link {
  display: inline-flex; align-items: center;
  height: 36px; padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  transition: background-color .15s var(--ease-micro), border-color .15s var(--ease-micro), transform .5s var(--spring-pop);
}
.entry .more-link { margin-top: 12px; }
.read-more::before, .entry .more-link::before,
.read-more::after, .entry .more-link::after {
  content: ""; width: 14px; height: 14px; flex: none;
  background: currentColor; color: var(--ink-2);
  transition: margin .5s var(--spring-pop), transform .5s var(--spring-pop), opacity .2s var(--ease-micro);
}
.read-more::before, .entry .more-link::before {
  margin-right: 8px;
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>') center / contain no-repeat;
}
.read-more::after, .entry .more-link::after {
  margin-left: -14px; opacity: 0; transform: translateX(10px);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14m-6-6 6 6-6 6"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14m-6-6 6 6-6 6"/></svg>') center / contain no-repeat;
}
.read-more:is(:hover, .is-hover), .entry .more-link:hover {
  background: color-mix(in srgb, var(--ink) 4%, var(--surface));
  border-color: color-mix(in srgb, var(--ink) 14%, var(--line));
  transform: scale(1.02);
}
.read-more:is(:hover, .is-hover)::before, .entry .more-link:hover::before {
  margin-right: -14px; opacity: 0; transform: translateX(-10px);
}
.read-more:is(:hover, .is-hover)::after, .entry .more-link:hover::after {
  margin-left: 8px; opacity: 1; transform: none;
}
.read-more:active, .entry .more-link:active {
  transform: scale(.96);
  transition-duration: .15s, .15s, .1s;
}
/* legacy truncation plugins append their own right-aligned "继续阅读>>" inside
   the content — one 阅读更多 per post is the theme's own button */
.home-entry a.read-more, .home-entry a.read-more + p:empty { display: none; }

/* sticky cover (Customizer: sticky-image) — the pinned post leads with its
   image: one hairline card, badge on the photo, title reads underneath */
.sticky-cover {
  position: relative; display: block;
  margin: 4px 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
  aspect-ratio: 21 / 9;
}
.sticky-cover img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform .6s var(--ease-micro);
}
@media (hover: hover) and (pointer: fine) {
  .sticky-cover:hover img { transform: scale(1.02); }
}
.sticky-badge {
  position: absolute; top: 12px; left: 12px; z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 10px;
  border-radius: 999px;
  background: var(--primary); color: var(--primary-contrast);
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  box-shadow: var(--shadow-1);
}
.sticky-badge::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

/* rail side (Customizer: sidebar-position) */
body.rail-left .home-grid { grid-template-columns: 280px minmax(0, 1fr); }
body.rail-left .home-grid > .home-main { order: 2; }
body.rail-left .home-grid .rail { order: 1; }

/* Single post: source order is always article → comments → rail. Desktop Grid
   places the rail beside the article in row one and keeps comments in the
   article column in row two. The rail's sticky containing block is the
   first-row boundary, so an asynchronous comment expansion cannot change it;
   on narrow screens the same DOM naturally becomes the desired reading order. */
.single-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  grid-template-areas:
    "article rail"
    "comments .";
  column-gap: 64px;
}
body.rail-left .single-layout {
  grid-template-columns: 280px minmax(0, 1fr);
  grid-template-areas:
    "rail article"
    ". comments";
}
.single-article { grid-area: article; min-width: 0; }
.single-layout .article-shell { max-width: 720px; margin-inline: 0; padding-inline: 0; }
.single-comments { grid-area: comments; min-width: 0; width: 100%; }
.single-rail-boundary { grid-area: rail; min-width: 0; align-self: stretch; }
.single-comments > #comments.comments-area,
.single-comments > #comments #wpdcom {
  width: 100%;
  max-width: none;
  margin-inline: 0;
}
.single-layout-no-rail .single-comments {
  max-width: 784px;
  margin-inline: auto;
  padding-inline: 32px;
}

/* optional list thumbnails (Customizer: list-thumbs) — fixed box, zero CLS */
.post-list a.row-link.has-thumb { display: flex; align-items: center; gap: 16px; }
.has-thumb .row-text { flex: 1; min-width: 0; }
.row-thumb { position: relative; flex: none; width: 72px; height: 72px; border-radius: 6px; overflow: hidden; background: var(--bg); }
.row-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.row-thumb::after { content: ""; position: absolute; inset: 0; border: 1px solid var(--line); border-radius: inherit; pointer-events: none; }

/* pagination — plain text (covers core links + wp-pagenavi) */
.pagination { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 32px; font-size: 15px; }
.pagination a, .pagination span,
.pagination .page-numbers,
.wp-pagenavi a, .wp-pagenavi span { padding: 4px 8px; border-radius: 4px; color: var(--ink-2); border: 0; }
.pagination a:hover, .wp-pagenavi a:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 6%, transparent); }
.pagination .current, .wp-pagenavi .current { color: var(--ink); font-weight: 600; }
.wp-pagenavi { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }

/* ==========================================================================
   Rail (sidebar)
   ========================================================================== */
.rail { position: static; align-self: start; display: flex; flex-direction: column; gap: 32px; }
/* app.js only enables sticky when the entire rail fits in the available
   viewport. A 1700px widget stack cannot meaningfully stick and otherwise
   appears to drift above the viewport while the article scrolls. */
.rail.is-stickable { position: sticky; top: calc(var(--header-h) + 32px); }
.profile-card { display: flex; flex-direction: column; gap: 8px; }
.profile-head { display: flex; align-items: center; gap: 16px; }
.avatar { width: 64px; height: 64px; border-radius: 50%; border: 1px solid var(--line); object-fit: cover; }
.profile-name { font-size: 16px; font-weight: 600; transition: color .15s var(--ease-micro); }
.profile-desc { font-size: 13px; color: var(--ink-2); }
/* the whole card fronts the site: avatar / name / bio all link home */
.profile-head a { display: block; }
.profile-link .avatar { transition: border-color .15s var(--ease-micro); }
.profile-link:hover .avatar { border-color: color-mix(in srgb, var(--ink) 30%, var(--line)); }
.profile-text:hover .profile-name { color: var(--primary); }
.social-links { display: flex; flex-wrap: wrap; gap: 4px; margin-left: -8px; list-style: none; }
.social-links a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: var(--r-md); color: var(--ink-2);
  transition: color .15s var(--ease-micro), background-color .15s var(--ease-micro);
}
.social-links a:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 6%, transparent); }

/* widgets: quiet lists */
.rail .widget h3, .footer-widgets .widget h3 { font-size: 13px; font-weight: 600; color: var(--ink-2); margin: 0 0 8px; }
.widget ul { list-style: none; }
.widget ul li { padding: 4px 0; font-size: 15px; }
.widget ul ul { padding-left: 16px; }
.widget a { color: var(--ink); transition: color .15s var(--ease-micro); }
.widget a:hover { color: var(--primary); }
.widget select { max-width: 100%; font: inherit; font-size: 14px; color: var(--ink); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: 6px 8px; }
.widget .post-date, .widget .rss-date { font-size: 13px; color: var(--ink-2); }
/* a menu item titled `_Separator_` (or a run of dashes) renders as a hairline */
li.menu-item-separator { pointer-events: none; }
.widget ul li.menu-item-separator { padding: 8px 0; }
.dropdown .menu-item-separator, .header-nav .menu-item-separator { padding: 4px 8px; display: block; }
.menu-separator { display: block; height: 1px; background: var(--line); border: 0; margin: 0; }
hr.menu-separator { margin: 8px 0; }
.mm-sep { display: block; height: 1px; background: var(--line); border: 0; margin: 8px 0; }
.widget .tag-cloud-link { display: inline-block; border: 1px solid var(--line); border-radius: var(--r-md); padding: 2px 8px; margin: 0 4px 8px 0; font-size: 13px !important; color: var(--ink-2); }
.widget .tag-cloud-link:hover { border-color: var(--ink-2); color: var(--ink); }
.widget_calendar table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.widget_calendar caption { color: var(--ink-2); padding-bottom: 8px; }
.widget_calendar td, .widget_calendar th { text-align: center; padding: 4px; }
.widget img { border-radius: var(--r-md); }

/* ==========================================================================
   Article (single / page)
   ========================================================================== */
.article-header { margin: 32px 0; }
.article-title { font-size: clamp(30px, 2.4vw + 22px, 42px); font-weight: 700; letter-spacing: -.015em; line-height: 1.3; }
.article-meta { margin-top: 16px; font-size: 13px; color: var(--ink-2); display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.article-meta .byline strong, .article-meta .byline a { color: var(--ink); font-weight: 600; }

.chip {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border: 1px solid var(--line); border-radius: var(--r-md);
  font-size: 13px; color: var(--ink-2); background: transparent;
  transition: border-color .15s var(--ease-micro), color .15s var(--ease-micro);
}
a.chip:hover { border-color: var(--ink-2); color: var(--ink); }

/* archive / search / 404 title block */
.page-head { margin: 16px 0 32px; }
.page-head h1 { font-size: 28px; font-weight: 700; letter-spacing: -.015em; line-height: 1.3; }
.page-head .sub { margin-top: 8px; font-size: 15px; color: var(--ink-2); }
.page-head .searchform { max-width: 400px; margin-top: 16px; }

/* ==========================================================================
   Entry content
   ========================================================================== */
.entry { font-size: 17px; line-height: 1.9; }
.entry > * + * { margin-top: 16px; }
.entry h1, .entry h2 { font-size: 24px; font-weight: 700; line-height: 1.4; margin-top: 64px; }
.entry h3, .entry h4 { font-size: 19px; font-weight: 600; line-height: 1.5; margin-top: 32px; }
.entry h5, .entry h6 { font-size: 17px; font-weight: 600; margin-top: 32px; }
.entry a {
  color: var(--primary);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--primary) 40%, transparent);
  transition: text-decoration-color .15s var(--ease-micro);
}
.entry a:hover { text-decoration-color: var(--primary); }
.entry ul, .entry ol { padding-left: 24px; }
.entry ul { list-style: disc; }
.entry ol { list-style: decimal; }
.entry li { margin-top: 4px; }
.entry li::marker { color: var(--ink-2); }
.entry strong, .entry b { font-weight: 600; }
.entry blockquote { border-left: 2px solid var(--line); padding-left: 16px; color: var(--ink-2); }
.entry figure { margin-top: 32px; }
.entry img { border-radius: var(--r-lg); }
.entry figure > img, .entry .wp-block-image img { border: 1px solid var(--line); border-radius: var(--r-lg); }
.entry figcaption, .entry .wp-caption-text { margin-top: 8px; font-size: 13px; color: var(--ink-2); text-align: center; }
.entry hr { border: 0; height: 1px; background: var(--line); margin: 32px 0; }
.entry code {
  font-family: var(--font-mono); font-size: .85em;
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  padding: 2px 5px; border-radius: 4px;
}
.entry ins { text-decoration: none; font-weight: 600; }
.entry table { border-collapse: collapse; width: 100%; font-size: 14px; line-height: 1.6; font-variant-numeric: tabular-nums; }
.entry th { text-align: left; font-weight: 600; border-bottom: 2px solid var(--line); padding: 8px; }
.entry td { border-bottom: 1px solid var(--line); padding: 8px; }
.entry .wp-block-table, .table-scroll { overflow-x: auto; }

/* code blocks + injected copy button */
.entry pre {
  margin: 16px 0 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 16px;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 13px; line-height: 1.7;
  font-variant-numeric: tabular-nums;
  white-space: pre-wrap; word-wrap: break-word;
}
.entry pre code { background: none; padding: 0; font-size: inherit; }
.code-block { position: relative; }
.code-block pre { margin-top: 0; }
.copy-btn {
  position: absolute; top: 8px; right: 8px;
  display: inline-flex; align-items: center; gap: 4px;
  height: 28px; padding: 0 8px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 13px; color: var(--ink-2);
  transition: color .15s var(--ease-micro), border-color .15s var(--ease-micro), opacity .15s var(--ease-micro);
}
.copy-btn:hover { color: var(--ink); border-color: var(--ink-2); }
.copy-btn .labels { position: relative; display: inline-block; min-width: 3em; text-align: center; }
.copy-btn .labels span { transition: opacity .12s var(--ease-micro); }
.copy-btn .l-done { position: absolute; inset: 0; opacity: 0; font-weight: 600; color: var(--ink); }
.copy-btn.copied .l-idle { opacity: 0; }
.copy-btn.copied .l-done { opacity: 1; }
.copy-btn svg { width: 13px; height: 13px; }
.copy-btn .check { stroke-dasharray: 14; stroke-dashoffset: 14; transition: stroke-dashoffset .2s var(--ease-micro) .05s; }
.copy-btn.copied .check { stroke-dashoffset: 0; }

/* changelog tags (content filter output); :has() removes the discs */
.log-tag {
  flex-shrink: 0;
  font-size: 13px; font-weight: 600; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 0 8px; line-height: 22px;
  font-variant-numeric: tabular-nums;
}
.entry ul:has(> li > .log-tag) { list-style: none; padding-left: 0; }
.entry li:has(> .log-tag) { display: flex; align-items: baseline; gap: 8px; margin-top: 8px; }

/* details / accordions — covers our .acc and plugin-emitted <details> alike.
   Lightweight Accordion ships gray fills, 18px type, display:list-item and a
   0.5s opacity keyframe that re-runs after our height animation lands (the
   "blink"); every rule below out-specifies its stylesheet and retakes them. */
.entry .lightweight-accordion { margin: 0; }
.entry details, details.acc, .entry .lightweight-accordion {
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 0; margin-top: 12px;
  background: transparent;
}
.entry .lightweight-accordion > details { border: 0; margin: 0; border-radius: inherit; }
.entry details + details,
.entry .lightweight-accordion + .lightweight-accordion { margin-top: 8px; }
.entry .lightweight-accordion .lightweight-accordion-body {
  border: 0; padding: 4px 12px 12px; background: transparent;
}
.entry details summary, details.acc summary,
.entry .lightweight-accordion details .lightweight-accordion-title {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 12px; font-size: 14px; font-weight: 600; line-height: 1.6;
  color: var(--ink); background: transparent;
  border-radius: calc(var(--r-md) - 1px);
  transition: background-color .15s var(--ease-micro);
}
.entry details summary:hover,
.entry .lightweight-accordion details .lightweight-accordion-title:hover { background: color-mix(in srgb, var(--ink) 4%, transparent); }
.entry details summary::-webkit-details-marker, details.acc summary::-webkit-details-marker { display: none; }
.entry details summary::marker, details.acc summary::marker { content: ""; }
.entry .lightweight-accordion .lightweight-accordion-title span,
.entry .lightweight-accordion .lightweight-accordion-title strong,
.entry .lightweight-accordion .lightweight-accordion-title p {
  display: inline; font-size: 14px; font-weight: 600; font-family: inherit; margin: 0;
}
.entry details summary::after {
  content: ""; width: 14px; height: 14px; flex-shrink: 0;
  background: currentColor; color: var(--ink-2);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>') center / contain no-repeat;
  transition: transform .25s var(--ease-micro);
}
.entry details[open]:not(.closing) > summary::after { transform: rotate(180deg); }
/* the blink fix: no second animation may touch the body once height has landed */
.entry details[open] summary ~ *,
.entry .lightweight-accordion details[open] summary ~ * { animation: none !important; }
.entry details > *:not(summary) { padding: 0 12px; }
.entry details > *:nth-child(2) { margin-top: 0; padding-top: 4px; }
.entry details > *:last-child { padding-bottom: 12px; }
.entry details .acc-clip { overflow: hidden; padding: 0; }
.entry details .acc-clip > * { padding: 4px 12px 12px; }
.entry details .acc-clip { font-size: 15px; line-height: 1.8; }
.entry details .acc-clip > * > * + *,
.entry details .acc-clip > p + p { margin-top: 8px; }
.entry details .acc-clip img { border-radius: 4px; }

/* embeds */
.video-container { position: relative; }
.video-container iframe { width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; }
.entry .wp-block-embed__wrapper iframe { max-width: 100%; }

/* alignment & captions (classic + block) */
.alignleft { float: left; margin: 4px 20px 8px 0; }
.alignright { float: right; margin: 4px 0 8px 20px; }
.aligncenter { display: block; margin-left: auto; margin-right: auto; }
.wp-caption { max-width: 100%; }
.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.gallery .gallery-item { margin: 0; }
.gallery img { border: 1px solid var(--line); border-radius: var(--r-md); }

/* notice helper (add class "notice" to a group/paragraph block) */
.notice, .entry .notice {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 16px;
  font-size: 15px; line-height: 1.7;
}
.notice strong { font-weight: 600; }

/* buttons inside content (block button) */
.entry .wp-block-button__link {
  background: var(--primary); color: var(--primary-contrast);
  border-radius: var(--r-md); padding: 8px 16px; font-size: 15px; font-weight: 600;
  text-decoration: none;
}

/* 文件下载卡片(core/file 区块,mr_file_block 重建):一张发丝线 surface 卡
   ——左类型图标、中文件名 + 扩展名/体积、右主色下载按钮。按钮 hover 是
   主题的签名弹簧手势:箭头沿下载方向穿过托盘离场,克隆从上方落位(过冲
   2px 压进托盘再弹回),离开时原路返回;整键 scale 与阅读更多同一族 */
.entry .wp-block-file { margin-bottom: 0; font-size: 15px; }
.entry .mr-file {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: border-color .15s var(--ease-micro);
}
.entry .mr-file:hover { border-color: color-mix(in srgb, var(--ink) 14%, var(--line)); }
.file-cap {
  position: relative; flex: none;
  width: 40px; height: 40px;
  background: color-mix(in srgb, var(--ink) 5%, transparent);
  border-radius: var(--r-md);
}
.file-cap::before {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 20px; height: 20px; background: var(--ink-2);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/></svg>') center / contain no-repeat;
}
.file-cap.is-zip::before {
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="5" rx="1"/><path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8"/><path d="M10 12h4"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="5" rx="1"/><path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8"/><path d="M10 12h4"/></svg>') center / contain no-repeat;
}
.file-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.entry .mr-file a.file-name {
  align-self: flex-start; max-width: 100%;
  color: var(--ink); font-size: 15px; font-weight: 600; line-height: 1.5;
  text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: color .15s var(--ease-micro);
}
.entry .mr-file a.file-name:hover { color: var(--primary); }
.file-kind { font-size: 13px; line-height: 1.4; color: var(--ink-2); font-variant-numeric: tabular-nums; }
/* 下载按钮:发丝线胶囊(和打赏/点赞同一语言)——静默 ink 洗底,
   hover 微亮 + 1.02 弹性放大,按压 .96;图标 download ⇄ check 手递手 */
.entry .mr-file a.wp-block-file__button {
  flex: none; display: inline-flex; align-items: center; gap: 10px;
  height: 36px; padding: 0 18px; margin: 0;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  border: 1px solid var(--line);
  color: var(--ink);
  border-radius: 999px;
  font-size: 13px; font-weight: 600; line-height: 1; letter-spacing: -.01em;
  text-decoration: none;
  transition: background-color .15s var(--ease-micro), border-color .15s var(--ease-micro),
              color .15s var(--ease-micro), transform .18s var(--ease-micro);
}
.entry .mr-file a.wp-block-file__button:is(:hover, :focus-visible, .is-hover) {
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  border-color: color-mix(in srgb, var(--ink) 16%, var(--line));
  color: var(--ink);
  opacity: 1;                     /* core 的 :hover{opacity:.85} 出局 */
}
/* the 1.02 lift is motion → gate hover to fine pointers (a touch tap fires a
   false hover); before :active so the press scale still wins on click */
@media (hover: hover) and (pointer: fine) {
  .entry .mr-file a.wp-block-file__button:is(:hover, :focus-visible, .is-hover) { transform: scale(1.02); }
}
.entry .mr-file a.wp-block-file__button:active {
  transform: scale(.96);
  transition-duration: .15s, .15s, .15s, .1s;
}
/* 图标手递手:离场字形 120ms 缩退让位,进场字形复用 --spring-pop
   (spring 600/25,峰值 +15% @ 143ms)弹入;hover 与移出方向对称 */
.dl-ico { position: relative; flex: none; width: 16px; height: 16px; }
.dl-ico::before, .dl-ico::after {
  content: ""; position: absolute; inset: 0; background: currentColor;
  will-change: transform, opacity;
}
.dl-ico::before {                 /* download:箭头入托盘 */
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/></svg>') center / contain no-repeat;
  transition: transform .5s var(--spring-pop), opacity .15s var(--ease-micro);
}
.dl-ico::after {                  /* check:缩到 .5 候场 */
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>') center / contain no-repeat;
  transform: scale(.5); opacity: 0;
  transition: transform .12s var(--ease-micro), opacity .12s var(--ease-micro);
}
/* icon hand-off is motion too → same gate; a keyboard user on a touch device
   still gets the focus outline, just not the swap */
@media (hover: hover) and (pointer: fine) {
  .entry .mr-file a.wp-block-file__button:is(:hover, :focus-visible, .is-hover) .dl-ico::before {
    transform: scale(.5); opacity: 0;
    transition: transform .12s var(--ease-micro), opacity .12s var(--ease-micro);
  }
  .entry .mr-file a.wp-block-file__button:is(:hover, :focus-visible, .is-hover) .dl-ico::after {
    transform: scale(1); opacity: 1;
    transition: transform .5s var(--spring-pop), opacity .15s var(--ease-micro);
  }
}
@media (max-width: 720px) {
  .entry .mr-file { flex-wrap: wrap; }
  .entry .mr-file .file-text { flex-basis: calc(100% - 54px); }
  .entry .mr-file a.wp-block-file__button { flex: 1; justify-content: center; margin-left: 54px; }
}

/* post password form */
.post-password-form input[type="password"] { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: 8px 12px; font: inherit; }
.post-password-form input[type="submit"] { background: var(--primary); color: var(--primary-contrast); border: 0; border-radius: var(--r-md); padding: 8px 16px; font: inherit; font-weight: 600; cursor: pointer; }

/* ==========================================================================
   Article footer: tags · author · post-nav · related
   ========================================================================== */
.article-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 64px; }

.author-bio { display: flex; gap: 16px; align-items: flex-start; margin-top: 32px; padding-top: 32px; border-top: 1px solid var(--line); }
.author-bio .avatar { width: 48px; height: 48px; }
.author-bio .bio-name { font-size: 15px; font-weight: 600; }
.author-bio .bio-desc { font-size: 15px; color: var(--ink-2); margin-top: 4px; }

.post-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 32px; padding-top: 32px; border-top: 1px solid var(--line); }
.post-nav a { display: block; }
.post-nav .dir { font-size: 13px; color: var(--ink-2); display: block; }
.post-nav .t { font-size: 15px; font-weight: 600; color: var(--ink); margin-top: 4px; display: block; transition: color .15s var(--ease-micro); }
.post-nav a:hover .t { color: var(--primary); }
.post-nav .next { text-align: right; }

.related { margin-top: 64px; }
.related h2 { font-size: 19px; font-weight: 600; margin-bottom: 8px; }
.related ul { list-style: none; }
.related li { border-top: 1px solid var(--line); }
.related li:first-child { border-top: 0; }
.related a { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 8px 0; }
.related .t { font-size: 15px; font-weight: 600; color: var(--ink); transition: color .15s var(--ease-micro); }
.related a:hover .t { color: var(--primary); }
.related time { font-size: 13px; color: var(--ink-2); flex-shrink: 0; }

/* ==========================================================================
   Comments (native, html5 markup) — wpDiscuz replaces this block if active
   ========================================================================== */
.comments-area {
  margin-top: 64px;
  scroll-margin-top: calc(var(--header-h) + 24px);
}
.comments-area .comments-title, .comments-area .comment-reply-title { font-size: 19px; font-weight: 600; margin-bottom: 16px; }
.comment-list, .comment-list .children { list-style: none; padding: 0; }
.comment-list > li { padding: 16px 0; }
.comment-list > li + li { border-top: 1px solid var(--line); }
.comment-list .children { margin: 16px 0 0 16px; padding-left: 16px; border-left: 2px solid var(--line); }
.comment-list .children li { padding: 16px 0 0; }
.comment-body { position: relative; padding-left: 52px; }
.comment-author { font-size: 15px; }
.comment-author .avatar {
  position: absolute; left: 0; top: 2px;
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--line);
}
.comment-author .fn { font-weight: 600; font-style: normal; }
.comment-author .says { display: none; }
.comment-metadata { font-size: 13px; color: var(--ink-2); margin-top: 2px; }
.comment-metadata a { color: var(--ink-2); }
.comment-content { font-size: 15px; line-height: 1.7; margin-top: 4px; }
.comment-content > * + * { margin-top: 8px; }
.reply { font-size: 13px; margin-top: 4px; }
.reply a { color: var(--ink-2); transition: color .15s var(--ease-micro); }
.reply a:hover { color: var(--primary); }
.bypostauthor > .comment-body .comment-author .fn::after {
  content: "作者";
  font-size: 11px; font-weight: 600; color: var(--primary);
  border: 1px solid color-mix(in srgb, var(--primary) 40%, transparent);
  border-radius: 4px; padding: 0 4px; line-height: 16px; margin-left: 8px;
  vertical-align: 2px;
}
.comment-awaiting-moderation { display: block; font-size: 13px; color: var(--ink-2); }
.comments-pagination { margin-top: 16px; }

.comment-respond { margin-top: 32px; }
.comment-form { display: grid; gap: 16px; }
.comment-form p { margin: 0; }
.comment-form label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.comment-form input[type="text"], .comment-form input[type="email"], .comment-form input[type="url"], .comment-form textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 8px 12px;
  font: inherit; font-size: 15px; color: var(--ink);
  transition: border-color .15s var(--ease-micro), box-shadow .15s var(--ease-micro);
}
.comment-form textarea { min-height: 120px; resize: vertical; }
.comment-form input:focus, .comment-form textarea:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}
.comment-form .comment-form-cookies-consent { display: flex; align-items: baseline; gap: 8px; font-size: 13px; color: var(--ink-2); }
.comment-form .comment-form-cookies-consent label { display: inline; font-weight: 400; font-size: 13px; }
.comment-form .form-submit input {
  background: var(--primary); color: var(--primary-contrast);
  border: 0; border-radius: var(--r-md);
  height: 40px; padding: 0 16px;
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  transition: background-color .15s var(--ease-micro), transform .15s var(--ease-micro);
}
.comment-form .form-submit input:hover { background: color-mix(in srgb, var(--primary) 88%, var(--ink)); }
.comment-form .form-submit input:active { transform: translateY(1px); }
.comment-notes, .logged-in-as { font-size: 13px; color: var(--ink-2); }
.comment-reply-link { font-size: 13px; }

/* ==========================================================================
   wpDiscuz (plugin) — retake every hardcoded gray/white with the tokens.
   Selector budget: `#comments #wpdcom` (two ids) outweighs the plugin's
   `#wpdcom …` rules and its inline settings CSS in both load orders.
   ========================================================================== */
#comments #wpdcom {
  margin-top: 64px; padding: 0;
  border-top: 1px solid var(--line);
  font-family: var(--font-sans);
  font-size: 15px; color: var(--ink);
}
#comments #wpdcom * { font-family: inherit; letter-spacing: normal; }
/* The reset above deliberately normalizes plugin text, but Font Awesome's
   private-use glyphs must keep their bundled webfont. macOS can sometimes
   find an incidental fallback; Windows usually renders an empty square. */
#comments #wpdcom .fa,
#comments #wpdcom .fas {
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
}
#comments #wpdcom .far {
  font-family: "Font Awesome 5 Free";
  font-weight: 400;
}
#comments #wpdcom .fab {
  font-family: "Font Awesome 5 Brands";
  font-weight: 400;
}
#comments #wpdcom a { color: var(--primary); }

/* form head: subscribe toggle + login row */
#comments #wpdcom .wpd-form-head { border-bottom: 1px solid var(--line); margin: 24px 0 8px; padding: 0 0 8px; }
#comments #wpdcom .wpd-sbs-toggle, #comments #wpdcom .wpd-sbs-toggle i { color: var(--ink-2); font-size: 13px; }
#comments #wpdcom .wpd-auth, #comments #wpdcom .wpd-login, #comments #wpdcom .wpd-login a { font-size: 13px; color: var(--ink-2); }

/* editor: one quiet bordered field, toolbar sits inside it */
#comments #wpdcom .wpdiscuz-textarea-wrap,
#comments #wpdcom .ql-container {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md) var(--r-md) 0 0;
  box-shadow: none;
}
#comments #wpdcom .wpdiscuz-textarea-wrap { border: 0; background: transparent; }
#comments #wpdcom .ql-editor { min-height: 72px; border: 0; background: transparent; }
#comments #wpdcom .ql-editor > *, #comments #wpdcom .ql-editor p { color: var(--ink); font-size: 15px; font-family: inherit; letter-spacing: normal; cursor: text; }
#comments #wpdcom .ql-editor::before { color: var(--ink-2); font-size: 15px; font-style: normal; letter-spacing: normal; }
#comments #wpdcom .ql-toolbar {
  background: color-mix(in srgb, var(--ink) 3%, var(--surface));
  border: 1px solid var(--line); border-top: 0;
  border-radius: 0 0 var(--r-md) var(--r-md);
}
#comments #wpdcom .ql-toolbar button .ql-stroke { stroke: var(--ink-2); }
#comments #wpdcom .ql-toolbar button .ql-fill { fill: var(--ink-2); }
#comments #wpdcom .ql-toolbar button:hover .ql-stroke, #comments #wpdcom .ql-toolbar button.ql-active .ql-stroke { stroke: var(--ink); color: var(--ink); }
#comments #wpdcom .ql-toolbar button:hover .ql-fill, #comments #wpdcom .ql-toolbar button.ql-active .ql-fill { fill: var(--ink); }
#comments #wpdcom .ql-toolbar button.ql-sourcecode { color: var(--ink-2); }
#comments #wpdcom .wpd-editor-char-counter { color: var(--ink-2); background: transparent; }
#comments #wpdcom .wpd-form .wpdiscuz-textarea-wrap textarea {
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: none; font-size: 15px;
}

/* name / email / any text input ("ID 那一栏") */
#comments #wpdcom input[type="text"],
#comments #wpdcom input[type="email"],
#comments #wpdcom input[type="url"],
#comments #wpdcom input[type="password"],
#comments #wpdcom select,
#comments #wpdcom .wpdiscuz-item input {
  background: var(--surface) !important;
  color: var(--ink) !important;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: none;
  font-size: 14px;
  min-height: 36px;
  transition: border-color .15s var(--ease-micro), box-shadow .15s var(--ease-micro);
}
#comments #wpdcom input:focus, #comments #wpdcom .ql-container.ql-focused,
#comments #wpdcom select:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}
#comments #wpdcom ::placeholder { color: var(--ink-2); opacity: 1; }
#comments #wpdcom .wpd-field-icon i { color: var(--ink-2); }
#comments #wpdcom .wpd-field-icon { opacity: .7; }
#comments #wpdcom label, #comments #wpdcom .wpdlb, #comments #wpdcom .wpd_label__text { color: var(--ink-2); font-size: 13px; }
#comments #wpdcom .wpd_label__check i.wpdicon-on { color: var(--primary); border-color: color-mix(in srgb, var(--primary) 40%, transparent); }
#comments #wpdcom .wpd_label__check i.wpdicon-off { color: var(--ink-2); border-color: var(--line); }
#comments #wpdcom .wpd-form-row .wpd-field { color: var(--ink-2); }

/* buttons: one primary, everything else quiet */
#comments #wpdcom .wpd-prim-button,
#comments #wpdcom input[type="submit"],
#comments #wpdcom .wc-field-submit input[type="button"] {
  background: var(--primary); color: var(--primary-contrast);
  border: 0; border-radius: var(--r-md);
  height: 36px; padding: 0 16px;
  font-size: 14px; font-weight: 600; line-height: 36px; letter-spacing: normal;
  box-shadow: none; cursor: pointer;
  transition: background-color .15s var(--ease-micro), transform .15s var(--ease-micro);
}
#comments #wpdcom .wpd-prim-button:hover, #comments #wpdcom input[type="submit"]:hover { background: color-mix(in srgb, var(--primary) 88%, var(--ink)); }
#comments #wpdcom .wpd-prim-button:active, #comments #wpdcom input[type="submit"]:active { transform: translateY(1px); }
#comments #wpdcom .wpd-button,
#comments #wpdcom .wpd-load-more-submit {
  background: transparent; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md);
  font-size: 14px; font-weight: 600; letter-spacing: normal; box-shadow: none;
}
#comments #wpdcom .wpd-button:hover, #comments #wpdcom .wpd-load-more-submit:hover { border-color: color-mix(in srgb, var(--ink) 26%, var(--line)); }

/* auto-load stand-in (app.js): the theme presses 「查看评论」 as the thread
   nears the viewport; wpDiscuz removes the button on click and its only
   feedback is a fixed gif at the page's top-right corner — an in-place
   note holds the button's spot until the thread lands */
#comments #wpdcom .mr-wpd-pressed { display: none; }
#comments #wpdcom .mr-wpd-loading {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px 0; margin: 10px 0;
  color: var(--ink-2); font-size: 14px;
}
#comments #wpdcom .mr-wpd-loading::before {
  content: ""; width: 15px; height: 15px; border-radius: 50%; flex: none;
  border: 2px solid var(--line); border-top-color: var(--primary);
  animation: mr-wpd-spin .7s linear infinite;
}
@keyframes mr-wpd-spin { to { transform: rotate(1turn); } }
@media (prefers-reduced-motion: reduce) {
  #comments #wpdcom .mr-wpd-loading::before { animation: none; border-top-color: var(--line); }
}

/* thread head: "N 条评论" as a plain strong line, quiet sorter */
#comments #wpdcom .wpd-thread-head { border-bottom: 1px solid var(--line); align-items: baseline; }
#comments #wpdcom .wpd-thread-head .wpd-thread-info {
  color: var(--ink); font-size: 16px; font-weight: 600;
  text-transform: none; letter-spacing: normal; padding-left: 0;
  border-bottom: 0;
}
#comments #wpdcom .wpd-thread-head .wpd-thread-info.wpd-reviews-tab { border-bottom: 0; }
#comments #wpdcom .wpd-thread-filter .wpdf-sorting { color: var(--ink-2); font-size: 13px; }
#comments #wpdcom .wpd-thread-filter .wpdf-sorting:hover { color: var(--ink); }
#comments #wpdcom .wpdf-sorting-dropdown {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-2); padding: 4px;
}
#comments #wpdcom .wpdf-sorting-dropdown a { color: var(--ink); border-radius: 4px; }
#comments #wpdcom .wpdf-sorting-dropdown a:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }

/* comments: hairline-separated, ink text, 2px reply rail */
#comments #wpdcom .wpd-comment { margin: 0; }
#comments #wpdcom .wpd-comment-wrap { border: 0; background: transparent; margin: 0; padding: 16px 0; }
#comments #wpdcom .wpd-comment + .wpd-comment > .wpd-comment-wrap { border-top: 1px solid var(--line); }
#comments #wpdcom .wpd-comment.wpd-reply .wpd-comment-wrap {
  border-top: 0; background: transparent;
  border-left: 2px solid var(--line);
  margin-left: 4px; padding: 12px 0 4px 16px;
}
#comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply { margin-left: 16px; }
#comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply .wpd-comment-wrap { margin-left: 0; }
#comments #wpdcom.wpd-layout-3 .wpd-thread-list { padding: 16px 0 0; }
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-right {
  flex: 1 1 auto; width: auto; min-width: 0; padding-bottom: 0;
  border: 0 !important;
}
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-header,
#comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-sticky-comment .wpd-comment-header {
  margin-left: 0; padding: 0; background: transparent;
}
#comments #wpdcom.wpd-layout-3.wpdiscuz_no_avatar .wpd-comment .wpd-comment-header .wpd-comment-author {
  padding-left: 0;
}
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-subheader {
  margin: 2px 0 0; border: 0 !important;
}
#comments #wpdcom .wpd-comment-author, #comments #wpdcom .wpd-comment-author a { color: var(--ink) !important; font-size: 15px; font-weight: 600; }
#comments #wpdcom .wpd-comment-author span.wpd-user-nicename { color: var(--ink-2); font-family: inherit; font-size: 13px; }
#comments #wpdcom .wpd-comment-date { color: var(--ink-2) !important; font-size: 13px !important; font-variant-numeric: tabular-nums; }
#comments #wpdcom .wpd-comment-text,
#comments #wpdcom .wpd-comment-text * { color: var(--ink); font-size: 15px; line-height: 1.7; letter-spacing: normal; }
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-text,
#comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply .wpd-comment-text { padding: 8px 0 4px; }
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-reply-to {
  flex-wrap: wrap; gap: 0 4px;
  margin: 2px 0 0; padding: 0;
  background: transparent; border: 0;
  color: var(--ink-2); font-style: normal;
}
#comments #wpdcom .wpd-comment-text a { color: var(--primary); }
#comments #wpdcom .wpd-comment-text blockquote { border-left: 2px solid var(--line); padding-left: 12px; color: var(--ink-2); background: transparent; }
#comments #wpdcom .wpd-comment-text code { font-family: var(--font-mono); font-size: .85em; background: color-mix(in srgb, var(--ink) 7%, transparent); padding: 2px 5px; border-radius: 4px; }
#comments #wpdcom .wpd-inline-feedback-wrapper { background: color-mix(in srgb, var(--warm) 10%, transparent); color: var(--ink-2); border-radius: var(--r-md); }
#comments #wpdcom .wpd-new-loaded-comment > .wpd-comment-wrap { background: color-mix(in srgb, var(--primary) 7%, transparent); border-radius: var(--r-md); }

/* role labels (settings ship green-on-white inline CSS) */
#comments #wpdcom .wpd-comment-label,
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-label {
  background: transparent !important; color: var(--primary) !important;
  border: 1px solid color-mix(in srgb, var(--primary) 40%, transparent) !important;
  border-radius: 4px; font-size: 11px; font-weight: 600; line-height: 16px; padding: 0 5px;
}
#comments #wpdcom .wpd-blog-administrator .wpd-comment-author,
#comments #wpdcom .wpd-blog-administrator .wpd-comment-author a { color: var(--ink) !important; }

/* footer row: votes + reply, quiet until hover */
#comments #wpdcom .wpd-comment-footer { color: var(--ink-2); }
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer,
#comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply .wpd-comment-footer {
  align-items: center; gap: 4px;
  margin: 8px 0 0; padding: 0; border: 0;
}
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-vote {
  margin: 0; padding: 0;
}
#comments #wpdcom .wpd-comment-footer .wpd-reply-button,
#comments #wpdcom .wpd-comment-footer .wpd-tools i,
#comments #wpdcom .wpd-comment-footer span { color: var(--ink-2); font-size: 13px; }
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-reply-button {
  display: inline-flex; align-items: center;
  min-height: 26px; padding: 0 8px;
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-md);
}
#comments #wpdcom .wpd-comment-footer .wpd-reply-button:hover { color: var(--ink); border-color: color-mix(in srgb, var(--ink) 26%, var(--line)); }
#comments #wpdcom .wpd-comment-footer .wpd-reply-button svg,
#comments #wpdcom .wpd-comment-footer .wpd-vote-up svg,
#comments #wpdcom .wpd-comment-footer .wpd-vote-down svg { fill: currentColor; }
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-vote-up,
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-vote-down {
  background: transparent; border: 1px solid var(--line); color: var(--ink-2);
  width: 26px; height: 26px; padding: 5px;
  transition: border-color .15s var(--ease-micro), color .15s var(--ease-micro);
}
/* pin the thumb glyphs: without this the unsized SVGs fill the whole 26px
   box (24px thumbs jammed against the circle) — 14px matches the tool icons */
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-vote-up svg,
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-vote-down svg {
  width: 14px; height: 14px; flex: none;
}
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-vote-up:hover,
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-vote-down:hover { border-color: var(--ink-2); color: var(--ink); }
#comments #wpdcom .wpd-comment-footer .wpd-vote-result {
  color: var(--ink-2); font-variant-numeric: tabular-nums;
  background: transparent; border-radius: 0; padding: 0 6px; line-height: 26px;
}
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-tool-wrap { padding-left: 8px; background: transparent; }
#comments #wpdcom.wpd-layout-3 .wpd-comment .wpd-comment-footer .wpd-tool-wrap i {
  width: 26px; height: 26px; padding: 5px;
  background: transparent; border: 1px solid var(--line); color: var(--ink-2);
}
#comments #wpdcom.wpd-layout-3 .wpd-comment-footer .wpd-toggle .wpd-view-replies {
  margin: 0; padding: 4px 8px;
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-md);
  color: var(--ink-2);
}
#comments #wpdcom .wpd-vote-up.wpd-up, #comments #wpdcom .wpd-vote-up.wpd-up i { color: var(--primary) !important; border-color: color-mix(in srgb, var(--primary) 50%, transparent) !important; }
#comments #wpdcom .wpd-vote-down.wpd-down, #comments #wpdcom .wpd-vote-down.wpd-down i { color: var(--danger) !important; border-color: color-mix(in srgb, var(--danger) 50%, transparent) !important; }

/* decorative FA icons off: the clock before dates, the speech bubble before
   "Reply to", the pencil on the last-edited line — the text carries itself */
#comments #wpdcom .wpd-comment-date > i,
#comments #wpdcom .wpd-reply-to > i,
#comments #wpdcom .wpd-comment-last-edited > i { display: none; }
#comments #wpdcom .wpd-comment-last-edited { color: var(--ink-2); font-size: 12px; font-style: normal; margin-top: 4px; }

/* replies: the plugin switches the vote buttons to display:inline and drops
   their padding, so the 26px box collapses and the unsized thumb SVGs blow
   up. Recreate the parent buttons' exact flex environment and every footer
   control resolves identically at both levels. */
#comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply .wpd-comment-footer .wpd-vote-up,
#comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply .wpd-comment-footer .wpd-vote-down {
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  padding: 5px; border: 1px solid var(--line);
}

/* subscribe bar + misc panels */
#comments #wpdcom .wpdiscuz-subscribe-bar { background: transparent; color: var(--ink-2); border: 0; padding: 8px 0; }
#comments #wpdcom .wpdiscuz-subscribe-form-intro { color: var(--ink-2); font-size: 13px; }
#comments #wpdcom .wc-bin-captcha, #comments #wpdcom .wpd-field-captcha { background: transparent; color: var(--ink-2); }
#comments #wpdcom .wpd-form .wpd-avatar img.avatar,
#comments #wpdcom .wpd-comment .avatar { background: var(--surface); border: 1px solid var(--line); padding: 0; border-radius: 50%; }
#comments #wpdcom hr { border: 0; height: 1px; background: var(--line); }
#comments #wpdcom .wpd-agreement-checkbox-label, #comments #wpdcom .wpd-agreement { color: var(--ink-2); font-size: 13px; }
#comments #wpdcom .wpdiscuz-comment-message { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); color: var(--ink); box-shadow: var(--shadow-2); }

/* ==========================================================================
   Donate with QRcode (打赏 / 点赞) — the stock 64px circle buttons become two
   quiet hairline pills on the article's own grid: 打赏 warms on hover, 点赞
   answers in Signal Blue and keeps the tint once counted. Press/release
   physics live in app.js (spring on transform). The plugin pins its sizes
   with !important, so the overrides pin the same properties back.
   ========================================================================== */
:root { --dwqrColor: var(--primary); }
#main .wbp-cbm {
  margin: 64px 0 0; padding: 32px 0 0;
  border-top: 1px solid var(--line);
  text-align: center; font-size: 0; clear: both;
}
#main .wbp-cbm .dwqr-inner { display: inline-flex; gap: 16px; }
#main .wbp-cbm .wb-btn-dwqr {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: auto !important; min-width: 0 !important; height: 40px !important;
  margin: 0; padding: 0 20px;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-md);
  line-height: normal !important;
  color: var(--ink-2);
  cursor: pointer;
  will-change: transform;
  transition: color .15s var(--ease-micro), border-color .15s var(--ease-micro), background-color .15s var(--ease-micro);
}
#main .wbp-cbm .wb-btn-dwqr svg,
#main .wbp-cbm .wb-btn-dwqr svg.wb-icon {
  position: static; top: auto; left: auto; margin: 0; flex: none;
  width: 16px; height: 16px;
  fill: currentColor;
}
#main .wbp-cbm .wb-btn-dwqr span {
  display: inline; padding: 0;
  font-size: 14px; font-weight: 600; line-height: 1 !important;
  color: inherit;
  font-variant-numeric: tabular-nums;
}
#main .wbp-cbm .wb-btn-dwqr:hover span, #main .wbp-cbm .wb-btn-dwqr:active span,
#main .wbp-cbm .wb-btn-dwqr.active span { color: inherit; }
#main .wbp-cbm .wb-btn-dwqr:hover svg, #main .wbp-cbm .wb-btn-dwqr:active svg,
#main .wbp-cbm .wb-btn-dwqr.active svg { fill: currentColor; }
#main .wbp-cbm .wb-btn-donate:hover, #main .wbp-cbm .wb-btn-donate:active {
  color: var(--warm);
  border-color: color-mix(in srgb, var(--warm) 45%, var(--line));
  background: color-mix(in srgb, var(--warm) 8%, var(--surface));
}
#main .wbp-cbm .wb-btn-like:hover, #main .wbp-cbm .wb-btn-like:active {
  color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--line));
  background: color-mix(in srgb, var(--primary) 8%, var(--surface));
}
/* already-liked: the tint stays */
#main .wbp-cbm .wb-btn-like.active, #main .wbp-cbm .wb-btn-like.active:hover {
  color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--line));
  background: color-mix(in srgb, var(--primary) 10%, var(--surface));
  cursor: default;
}

/* the QR dialog joins the surface system; the code itself keeps a white
   plate so it stays scannable in dark mode */
body .wbui-mask { background: rgba(0, 0, 0, .5); }
body .wbui-dialog .wbui-child {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  color: var(--ink);
  font-family: var(--font-sans);
}
body .wbui-title {
  line-height: 44px; padding-left: 16px;
  border-bottom: 1px solid var(--line);
  font-size: 15px; font-weight: 600; color: var(--ink);
}
body .wbui-close { line-height: 44px; }
html[data-theme="dark"] .wbui-close i { filter: invert(1) brightness(1.2); }
@media (prefers-color-scheme: dark) {
  html:not([data-theme]) .wbui-close i { filter: invert(1) brightness(1.2); }
}
body .wbui-dialog .wbui-cont { padding: 16px 24px 24px; }
body .wbui-dwqr-donate .tab-navs:empty { display: none; }
body .wbui-dwqr-donate .tab-cont .pic { margin-top: 16px; }
body .wbui-dwqr-donate .tab-nav-item { border-bottom: 1px solid var(--line); color: var(--ink-2); font-weight: 600; }
body .wbui-dwqr-donate .tab-nav-item.current { border-top: 1px solid var(--line); border-bottom-color: transparent; color: var(--ink); }
body .wbui-dwqr-donate .tab-nav-item + .tab-nav-item { border-left: 1px solid var(--line); }
body .wbui-dwqr-donate .tab-cont p { color: var(--ink-2); font-size: 13px; padding-bottom: 16px; }
body .wbui-dwqr-donate .tab-cont .hl { color: var(--primary); }
body .wbui-dwqr-donate .tab-cont .pic {
  width: 155px; height: 155px; box-sizing: content-box;
  background: #fff; padding: 8px;
  border: 1px solid var(--line); border-radius: var(--r-md);
}

/* ==========================================================================
   Echo Knowledge Base (plugin) — the stock look stacks a white plate, gray
   shadowed slabs and gray header bars four levels deep. Flatten to a single
   level of hairline cards on the page background; tokens make dark mode work.
   (!important pairs with the plugin's inline settings CSS, which also uses it.)
   ========================================================================== */
body.eckb-kb-current-theme-template-main-page .article-shell { max-width: 1128px; }
#main .entry #epkb-modular-main-page-container { font-family: var(--font-sans); }
#main .entry #epkb-modular-main-page-container #epkb-content-container,
#main .entry #epkb-modular-main-page-container .epkb-ml__module,
#main .entry #epkb-modular-main-page-container #epkb-ml__module-search {
  background: transparent !important;
  box-shadow: none !important;
}
#main .entry #epkb-modular-main-page-container #epkb-ml-basic-layout { background: transparent !important; box-shadow: none !important; }
#main .entry #epkb-modular-main-page-container .epkb-top-category-box,
#main .entry #epkb-modular-main-page-container .epkb-ml-article-section {
  background: var(--surface) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--r-lg) !important;
  box-shadow: none !important;
  overflow: hidden;
}
#main .entry #epkb-modular-main-page-container .section-head {
  background: transparent !important;
  border: 0 !important;
  border-bottom: 1px solid var(--line) !important;
  border-radius: 0 !important;
  padding: 12px 16px !important;
}
#main .entry #epkb-modular-main-page-container .section-head *,
#main .entry #epkb-modular-main-page-container .epkb-cat-name,
#main .entry #epkb-modular-main-page-container .epkb-category-level-1 {
  color: var(--ink) !important;
  background: transparent !important;
}
#main .entry #epkb-modular-main-page-container .section-head .epkb-cat-desc { color: var(--ink-2) !important; font-size: 13px; }
#main .entry #epkb-modular-main-page-container .section-body { background: transparent !important; }
#main .entry #epkb-modular-main-page-container .eckb-article-title,
#main .entry #epkb-modular-main-page-container .eckb-article-title span,
#main .entry #epkb-modular-main-page-container .epkb-ml-article-container a {
  color: var(--ink) !important;
  font-size: 14px;
  text-decoration: none;
  transition: color .15s var(--ease-micro);
}
#main .entry #epkb-modular-main-page-container .eckb-article-title:hover,
#main .entry #epkb-modular-main-page-container .eckb-article-title:hover span,
#main .entry #epkb-modular-main-page-container .epkb-ml-article-container a:hover { color: var(--primary) !important; }
#main .entry #epkb-modular-main-page-container .eckb-article-title .epkbfa,
#main .entry #epkb-modular-main-page-container .epkb-ml-article-container .epkbfa { color: var(--ink-2) !important; }
#main .entry #epkb-modular-main-page-container .epkb-section-body-hr, #main .entry #epkb-modular-main-page-container hr { background: var(--line); border: 0; height: 1px; }
#main .entry #epkb-modular-main-page-container .epkb-ml-articles-show-more,
#main .entry #epkb-modular-main-page-container .epkb-show-all-articles { color: var(--ink-2) !important; }
#main .entry #epkb-modular-main-page-container .epkb-ml-articles-show-more:hover,
#main .entry #epkb-modular-main-page-container .epkb-show-all-articles:hover { color: var(--primary) !important; }

/* KB search: one quiet field, no box-in-box (the plugin's settings CSS runs
   up to four ids deep with !important — out-id it) */
#main #epkb-modular-main-page-container #epkb-ml__module-search #epkb-ml-search-form #epkb-ml-search-box {
  background: transparent !important;
  box-shadow: none !important;
  border: 0 !important;
  padding: 0 !important;
  gap: 8px;
}
#main #epkb-modular-main-page-container #epkb-ml__module-search #epkb-ml-search-form .epkb-ml-search-box__input {
  background: var(--surface) !important;
  color: var(--ink) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--r-md) !important;
  height: 44px !important;
  padding: 0 12px !important;
  font-size: 15px !important;
  box-shadow: none !important;
}
#main #epkb-modular-main-page-container #epkb-ml__module-search #epkb-ml-search-form .epkb-ml-search-box__input:focus {
  outline: none;
  border-color: var(--primary) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent) !important;
}
#main .entry #epkb-modular-main-page-container ::placeholder { color: var(--ink-2); }
#main #epkb-modular-main-page-container #epkb-ml__module-search #epkb-ml-search-form .epkb-ml-search-box__btn,
#main #epkb-modular-main-page-container #epkb-ml__module-search #epkb-ml-search-form button {
  background: var(--primary) !important;
  color: var(--primary-contrast) !important;
  border: 0 !important;
  border-radius: var(--r-md) !important;
  height: 44px !important;
  box-shadow: none !important;
  font-size: 15px !important;
  font-weight: 600;
}
#main #epkb-modular-main-page-container #epkb-ml__module-search #epkb-ml-search-form .epkb-ml-search-box__btn * { color: var(--primary-contrast) !important; }
#main .entry #epkb-modular-main-page-container .epkb-ml-search-form { align-items: center; }
#main .entry #epkb-modular-main-page-container .epkb-doc-search-container__title,
#main .entry #epkb-modular-main-page-container .epkb-ml-search-title { color: var(--ink) !important; }

/* ==========================================================================
   Front widgets · footer · back-to-top
   ========================================================================== */
.front-widgets { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; margin-bottom: 64px; }
.front-widgets .widget + .widget { margin-top: 16px; }

.site-footer { margin-top: 64px; border-top: 1px solid var(--line); }
.footer-widgets { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 32px; padding: 32px 0 0; }
.footer-nav { padding-top: 32px; }
.footer-menu { display: flex; flex-wrap: wrap; gap: 8px 24px; font-size: 13px; }
.footer-menu a { color: var(--ink-2); transition: color .15s var(--ease-micro); }
.footer-menu a:hover { color: var(--ink); }
.format-media { margin-bottom: 32px; }
.format-media img { display: block; width: 100%; height: auto; border-radius: 8px; }
.format-media .gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.format-media .gallery img { border-radius: 6px; }
.footer-bar { padding: 32px 0 64px; display: flex; flex-wrap: wrap; gap: 8px 32px; align-items: center; font-size: 13px; color: var(--ink-2); }
.footer-bar a { color: var(--ink-2); transition: color .15s var(--ease-micro); }
.footer-bar a:hover { color: var(--ink); }
.footer-bar .social-links { margin-left: auto; }
#footer-logo { max-height: 40px; width: auto; }

.back-top {
  position: fixed; right: 32px; bottom: 32px; z-index: 70;
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  color: var(--ink);
  opacity: 0; transform: translateY(12px); pointer-events: none;
  transition: opacity .2s var(--ease-micro), transform .2s var(--ease-micro), box-shadow .15s var(--ease-micro);
}
.back-top.show { opacity: 1; transform: none; pointer-events: auto; }
.back-top:hover { box-shadow: var(--shadow-2); }
.back-top svg { width: 18px; height: 18px; }

/* ==========================================================================
   View transitions
   —— theme toggle: same-document radial reveal. app.js animates a
      constant-speed clip-path on the new-root snapshot via WAAPI; the
      circle overshoots the far corner by 12% so the wavefront exits the
      screen still at full speed (its landing never shows on-screen), and
      sweep time scales with the radius so every display plays the reveal
      in full. The compositor owns every frame; html.vt-theme scopes it.
   —— navigation: cross-document crossfade; header / rail / footer hold still,
      the clicked title morphs into the article title and back again (JS tags
      `article-title` on the matching pair at pageswap / pagereveal)
   ========================================================================== */
@view-transition { navigation: auto; }

/* Keep the destination interactive while the transition plays. The snapshot
   overlay sits in the top layer and captures clicks by default, so a fast
   click during the animation — into an article, or Back to the list — would
   land on the frozen snapshot and do nothing until it finished. Letting
   pointer events fall through to the live page underneath makes the transition
   interruptible: the click hits the real link and navigates immediately. The
   snapshots are never hit-testable themselves, so only the root overlay needs
   this; the morphing title/root keep animating untouched. */
::view-transition { pointer-events: none; }

/* theme reveal: root only, nothing else may split off; JS animates new(root) */
html.vt-theme::view-transition-old(root), html.vt-theme::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.vt-theme::view-transition-old(root) { z-index: 1; }
html.vt-theme::view-transition-new(root) { z-index: 2; }
html.vt-theme .site-header, html.vt-theme .rail, html.vt-theme .site-footer, html.vt-theme .back-top { view-transition-name: none !important; }
/* Token-driven component transitions would otherwise keep repainting inside
   the new root snapshot while it reveals, which causes the mid-flight hitch. */
html.vt-theme *, html.vt-theme *::before, html.vt-theme *::after,
html.theme-changing *, html.theme-changing *::before, html.theme-changing *::after { transition: none !important; }

/* navigation: stable chrome does not take part in the crossfade */
.site-header { view-transition-name: site-header; }
.rail { view-transition-name: rail; }
.site-footer { view-transition-name: site-footer; }
.back-top { view-transition-name: back-top; }
::view-transition-old(root) { animation-duration: .18s; }
::view-transition-new(root) { animation-duration: .26s; }
::view-transition-group(article-title) {
  animation-duration: .3s;
  animation-timing-function: var(--ease-micro);
}
::view-transition-old(article-title), ::view-transition-new(article-title) {
  animation-duration: .3s;
  height: 100%; width: auto;         /* keep the type's aspect while the box morphs */
}
::view-transition-group(site-header) { z-index: 10; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  html.vt-theme::view-transition-old(root), html.vt-theme::view-transition-new(root) { animation: none !important; }
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1080px) {
  .home-grid { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  body.rail-left .home-grid { grid-template-columns: minmax(0, 1fr); }
  body.rail-left .home-grid > .home-main, body.rail-left .home-grid .rail { order: initial; }
  .single-layout,
  body.rail-left .single-layout {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "article" "comments" "rail";
    row-gap: 32px;
  }
  .rail, .rail.is-stickable { position: static; flex-direction: row; flex-wrap: wrap; gap: 32px; border-top: 1px solid var(--line); padding-top: 32px; }
  .rail > * { flex: 1 1 240px; }
}
@media (max-width: 900px) {
  .header-nav { display: none; }
  .burger { display: inline-flex; }
  .header-actions { margin-left: auto; }
}
@media (max-width: 720px) {
  .shell, .article-shell { padding-inline: 16px; }
  .single-layout-no-rail .single-comments { padding-inline: 16px; }
  .brand-desc { display: none; }
  .release-card { flex-direction: column; align-items: stretch; padding: 16px; margin-bottom: 32px; }
  .release-card.has-media { grid-template-columns: minmax(0, 1fr); grid-template-areas: "media" "info" "action"; row-gap: 12px; }
  .release-media { aspect-ratio: 16 / 9; }
  .release-card.has-media .release-info { align-self: auto; }
  .release-action { flex-direction: row; align-items: center; justify-content: space-between; }
  .release-title { font-size: 24px; }
  .entry { font-size: 16px; }
  .entry h1, .entry h2 { margin-top: 32px; }
  .post-list { margin-inline: -8px; }
  .post-list a.row-link { padding: 16px 8px; }
  .post-list a.row-link.has-thumb { gap: 12px; }
  .row-thumb { width: 56px; height: 56px; }
  .post-list li::before { left: 8px; right: 8px; }
  .post-nav { grid-template-columns: 1fr; }
  .post-nav .next { text-align: left; }
  .front-widgets { grid-template-columns: 1fr; }
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .back-top { right: 16px; bottom: 16px; }
  .mobile-menu-inner { padding-inline: 16px; }
  .comment-list .children { margin-left: 8px; padding-left: 8px; }
  #comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply { margin-left: 8px; }
  #comments #wpdcom.wpd-layout-3 .wpd-comment.wpd-reply .wpd-comment-wrap { padding-left: 8px; }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
  html { scroll-behavior: auto; }
}
