/* ===== jirai.css ===== */
/* ============================================================
   jirai — 地雷系 theme
   黑 / 深紫 / 霓虹粉 · 蕾丝 · 心形 · 扫描线
   ============================================================ */

:root {
  color-scheme: dark;
  /* ---------- 表面层级（elevation）----------
     实测旧值：card 相对页面只有 1.06:1、card-2 相对 card 只有 1.02:1，
     层级差基本看不见，卡片没有「浮起」感。重排为四级递进，
     每级对上一级约 1.13–1.20:1 —— 在深色界面里刚好可辨，又不破坏氛围。 */
  --bg: #07040a;        /* 页面底（L0） */
  --bg-soft: #0e0812;   /* 次级面板（L1） ≈ 1.08:1 vs L0 */
  --bg-card: #17101c;   /* 卡片（L2）     ≈ 1.13:1 vs L1 */
  --bg-card-2: #22172a; /* 卡片内浮层（L3）≈ 1.13:1 vs L2 */
  --bg-raise: #2b1e34;  /* 悬停 / 激活表面 */
  --pink: #ff2d78;
  --pink-soft: #ff7ab8;
  --pink-deep: #c9124f;
  --purple: #a855f7;
  --purple-deep: #6d28d9;
  --text: #ece4ee;
  --text-dim: #a596ad;
  --text-faint: #6b5d73;
  /* 以下四色原先是散落在各文件里的字面值（#9a8ba4 出现了 16 次），
     都是小字可读性所需的层级，收进 token 以便统一调整。 */
  --text-bright: #ffffff;   /* 强调：悬停、当前项 */
  --text-head: #e6dcec;     /* 标题：比正文亮一档 */
  --text-mute: #9a8ba4;     /* 元数据/页脚：实测 6.41:1，小字达标 */
  --text-mute-2: #8d7f98;   /* 更弱一档，仅用于非关键编号 */
  /* 状态色 */
  --warn: #ffb020;
  --bad: #ff6b6b;
  --line: #35263d;      /* 亮一档，让卡片边界在更深底色上仍可辨 */
  /* ---------- 强调色的通道分解 + 透明度标尺 ----------
     审计发现同一个霓虹粉被手写了 135 次 rgba(255, 45, 120, α)，
     共用掉 115 种互不成比例的 alpha 值。改色时得全局替换几十处。
     拆成 RGB 通道 + 12 级透明度标尺后，语义清晰且计算值完全不变
     （rgb(R G B / a) 与 rgba(R, G, B, a) 渲染结果一致）。 */
  --pink-rgb: 255 45 120;
  --purple-rgb: 168 85 247;
  --seal-rgb: 192 57 43;
  --ink-rgb: 0 0 0;
  /* 透明度标尺：按用途分级而非线性取值 */
  --a-1: .04;   --a-2: .06;   --a-3: .10;   --a-4: .14;
  --a-5: .18;   --a-6: .24;   --a-7: .30;   --a-8: .38;
  --a-9: .48;   --a-10: .62;  --a-11: .78;  --a-12: 1;
  --line-pink: rgb(255 45 120 / .35);
  --glow-pink: 0 0 6px rgb(255 45 120 / .55), 0 0 18px rgb(255 45 120 / .28);
  --glow-soft: 0 0 12px rgba(255, 45, 120, .18);
  /* 系统字体栈：中文用衬线（宋体系），拉丁优先 Georgia/Times，
     不再依赖外部 Web 字体（详见 _config.yml 的 webfont 说明） */
  --font-head: Georgia, 'Times New Roman', 'Songti SC', 'Source Han Serif SC', 'Noto Serif CJK SC', SimSun, 'Yu Mincho', serif;
  --font-body: system-ui, -apple-system, 'PingFang SC', 'Microsoft YaHei', 'Hiragino Sans', 'Noto Sans CJK SC', sans-serif;
  --font-mono: ui-monospace, 'Cascadia Code', 'JetBrains Mono', Consolas, 'Courier New', monospace;
  --radius: 14px;
  --nav-h: 62px;
  /* 实测旧值 1120 时，1440 视口下内容只占 54%、右侧空 480px，版面失衡。
     放宽到 1280，配合 820/280 分栏，占比约 73%。 */
  --maxw: 1280px;

  /* ---------- 字号标尺 ----------
     基准 16px，小字步进约 1.15×，标题步进约 1.22×。
     原本全站有 18 种互不成比例的字号（含 9.5 / 10.5 / 11.5 / 15.5 等
     手工试出来的值），收敛到 9 级。 */
  --fs-3xs: 8px;      /* 纯装饰性记号 */
  --fs-2xs: 10px;     /* 图形化标签、印章副文案 */
  --fs-xs: 11.5px;    /* 元数据、等宽标签 */
  --fs-sm: 13.5px;    /* 次要说明、批注 */
  --fs-base: 15.5px;  /* 界面正文 */
  --fs-md: 16px;      /* 长文正文 */
  --fs-lg: 19px;      /* 小标题 */
  --fs-xl: 23px;      /* 区块标题 */
  --fs-2xl: 29px;     /* 页面主标题 */
  --fs-3xl: 35px;     /* 首屏标题（大字级时才出现） */

  /* ---------- 行高 ----------
     原来卡片区 1.77、正文段 1.98 两套节奏互相打架，统一为三种用途。 */
  --lh-tight: 1.3;    /* 标题 */
  --lh-snug: 1.55;    /* 界面文字、列表 */
  --lh-body: 1.95;    /* 长文正文 */

  /* ---------- 间距标尺（2px 基准）----------
     原本凭直觉定了 4px 基准的 11 级，但实测 351 个间距值里有 41 种，
     且大量集中在 6 / 10 / 14 / 2px —— 说明这个设计真正的节奏是 2px。
     4px 基准会让 6→4、10→8、14→12 全部产生 2px 漂移，改坏版面。
     补入子级后共 18 级，覆盖原有分布且不产生可见位移。 */
  --sp-0-5: 2px;
  --sp-1: 4px;
  --sp-1-5: 6px;
  --sp-2: 8px;
  --sp-2-5: 10px;
  --sp-3: 12px;
  --sp-3-5: 14px;
  --sp-4: 16px;
  --sp-4-5: 18px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 32px;
  --sp-8: 40px;
  --sp-9: 56px;
  --sp-10: 72px;
  --sp-11: 96px;
  /* 奇数级（5/7/9/11/13…）：刻意保留的半级微调，例如药丸按钮的
     padding: 3px 11px、徽标的 7px 16px。吸附到偶数会产生 1px 漂移，
     反而破坏原有视觉对齐，故单列一级命名。 */
  --sp-h1: 5px;
  --sp-h2: 7px;
  --sp-h3: 9px;
  --sp-h4: 11px;
  --sp-h5: 13px;
  --sp-h6: 15px;
  /* 非 2px 网格的大额值：吸附仅漂 1px（不可见），收进标尺避免孤立字面值 */
  --sp-x1: 30px;
  --sp-x2: 34px;
  --sp-x3: 38px;
  --sp-x4: 44px;
  --sp-x5: 46px;
  --sp-x6: 50px;
  --sp-x7: 52px;
  --sp-x8: 60px;
  --sp-x9: 64px;
  /* 大额偏移：装饰层专用，不属于版面节奏，保留独立命名以免被吸附 */
  --offset-deco-sm: -17px;
  --offset-deco-md: -120px;
  --offset-deco-lg: -206px;

  /* ---------- 版面节奏 ---------- */
  --gutter: clamp(16px, 4vw, 28px);
  --measure: 66ch;    /* 正文最佳行长上限 */

  /* ---------- 动效标尺 ----------
     审计发现原来有 16 种 transition 时长、22 种动画时长，
     缓动里 58 处是随手写的 ease。这里收敛成有语义的三档时长 + 三种缓动，
     并按「进入 / 离开 / 标准」区分曲线，让全站动作手感一致。 */
  --dur-1: .16s;      /* 微交互：hover、active、聚焦 */
  --dur-2: .26s;      /* 标准过渡：显隐、位移、颜色切换 */
  --dur-3: .45s;      /* 入场揭示：面板、抽屉、大幅位移 */
  --dur-4: .85s;      /* 场景级：幕布、开机帘 */

  --ease-std: cubic-bezier(.4, 0, .2, 1);      /* 通用：进出对称 */
  --ease-in: cubic-bezier(.4, 0, 1, 1);        /* 离开：加速淡出 */
  --ease-out: cubic-bezier(.16, 1, .3, 1);     /* 进入：快起慢收 */
  --ease-spring: cubic-bezier(.2, .8, .3, 1.06); /* 弹性：轻微回弹 */
  --ease-curtain: cubic-bezier(.76, 0, .24, 1);  /* 幕布：两端极缓、中间极快 */
  --ease-shake: cubic-bezier(.36, .07, .19, .97); /* 抖动：不规则震颤 */
  --ease-loop: linear;                          /* 循环：跑马灯、扫描 */
}

* { box-sizing: border-box; }

/* 内联 SVG 图标：给所有图标一个基准尺寸，
   并禁止 flex / list-item 容器把它拉伸成巨大色块 */
.ico {
  width: 13px;
  height: 13px;
  flex: none;
  display: inline-block;
  vertical-align: -0.14em;
}

svg { overflow: visible; }

html { scroll-behavior: auto; scrollbar-gutter: stable; scroll-padding-top: 96px; }

/* 面板和阅读浮层共用的轻淡入，不接管页面导航。 */
@keyframes page-out { to { opacity: 0; } }
@keyframes page-in { from { opacity: 0; } }

body {
  margin: 0;
  background-color: var(--bg);
  background-image:
    radial-gradient(1100px 620px at 12% -8%, rgba(255, 45, 120, .13), transparent 62%),
    radial-gradient(900px 560px at 92% 4%, rgba(168, 85, 247, .12), transparent 60%),
    radial-gradient(760px 520px at 50% 112%, rgba(201, 18, 79, .10), transparent 66%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg fill='%23ff2d78' fill-opacity='0.055'%3E%3Ccircle cx='2' cy='2' r='1'/%3E%3Ccircle cx='18' cy='18' r='1'/%3E%3C/g%3E%3C/svg%3E");
  background-attachment: fixed, fixed, fixed, fixed;
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-snug);
  letter-spacing: 0.02em;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

body::before {
  /* 扫描线 */
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9998;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, .022) 0px,
    rgba(255, 255, 255, .022) 1px,
    transparent 1px,
    transparent 3px
  );
  mix-blend-mode: overlay;
}

body.no-scanline::before { display: none; }

::selection { background: var(--pink); color: #fff; text-shadow: none; }

a { color: var(--pink-soft); text-decoration: none; transition: color var(--dur-1) var(--ease-std), text-shadow var(--dur-1) var(--ease-std); }
a:hover { color: #fff; text-shadow: var(--glow-pink); }

.skip-link { position: fixed; top: 12px; left: 20px; z-index: 11000; padding: 12px 18px; border: 1px solid var(--pink-soft); border-radius: 3px; color: var(--text); background: #160c1d; transform: translateY(-180%); }
.skip-link:focus { transform: translateY(0); }

img { max-width: 100%; height: auto; border-radius: 8px; }

hr {
  border: 0;
  height: 22px;
  margin: var(--sp-x2) 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: auto 22px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='22' viewBox='0 0 120 22'%3E%3Cg fill='none' stroke='%23ff2d78' stroke-opacity='0.55' stroke-width='1.2'%3E%3Cpath d='M0 11h38M82 11h38'/%3E%3C/g%3E%3Cpath d='M60 4c2.4 3.2 6 5.2 6 8.2a6 6 0 0 1-12 0c0-3 3.6-5 6-8.2z' transform='translate(0 1.6)' fill='none' stroke='%23ff2d78' stroke-opacity='0.8'/%3E%3Ccircle cx='45' cy='11' r='2' fill='%23ff2d78' fill-opacity='0.6'/%3E%3Ccircle cx='75' cy='11' r='2' fill='%23ff2d78' fill-opacity='0.6'/%3E%3C/svg%3E");
}

/* ---------------------------------------------- 顶部导航 */
.nav {
  position: sticky;
  top: 0;
  z-index: 900;
  height: var(--nav-h);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  background: rgba(8, 5, 10, .82);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(255, 45, 120, .18), 0 10px 30px rgba(0, 0, 0, .6);
}

.nav::after {
  /* 导航底部蕾丝边 */
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -11px;
  height: 11px;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='11' viewBox='0 0 24 11'%3E%3Cpath d='M0 0h24v2c-2 0-3 1.4-3 3.2S23 8.4 24 8.4V11H0V8.4c1 0 3-1.4 3-3.2S1 2 0 2z' fill='%23ff2d78' fill-opacity='0.14'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  background-size: 24px 11px;
  opacity: .9;
}

body.no-lace .nav::after { display: none; }

.nav-inner {
  max-width: var(--maxw);
  height: 100%;
  margin: 0 auto;
  padding: 0 var(--sp-5);
  display: flex;
  align-items: center;
  gap: var(--sp-4-5);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2-5);
  font-family: var(--font-head);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  letter-spacing: 0.06em;
}
.brand:hover { color: #fff; text-shadow: var(--glow-pink); }
.brand .brand-mark {
  width: 22px; height: 22px;
  flex: none;
  color: var(--pink);
  filter: drop-shadow(0 0 5px rgba(255, 45, 120, .8));
  animation: heartbeat 2.6s var(--ease-std) infinite;
}
.brand .brand-sub {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  letter-spacing: .12em;
  text-transform: uppercase;
}

@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  12% { transform: scale(1.18); }
  24% { transform: scale(1); }
  36% { transform: scale(1.12); }
  48% { transform: scale(1); }
}

.nav-links {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  list-style: none;
  padding: 0;
}

.nav-links a {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-1-5);
  padding: var(--sp-h2) var(--sp-h5);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  border: 1px solid transparent;
  border-radius: 999px;
  letter-spacing: .04em;
  transition: color .16s ease, background-color .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.nav-links a .ico { width: 13px; height: 13px; opacity: .8; }
.nav-links a:hover {
  color: #fff;
  border-color: var(--line-pink);
  background: rgba(255, 45, 120, .09);
  text-shadow: var(--glow-pink);
}
.nav-links a.active {
  color: #fff;
  border-color: var(--pink);
  background: linear-gradient(180deg, rgba(255, 45, 120, .22), rgba(168, 85, 247, .12));
  box-shadow: var(--glow-soft), inset 0 0 12px rgba(255, 45, 120, .12);
}
.nav-links a.active::after {
  content: '';
  position: absolute;
  left: 50%; bottom: -3px;
  width: 5px; height: 5px;
  margin-left: -2.5px;
  background: var(--pink);
  transform: rotate(45deg);
  box-shadow: var(--glow-pink);
}

.nav-toggle {
  display: none;
  margin-left: auto;
  width: 40px; height: 36px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--line-pink);
  border-radius: 10px;
  color: var(--pink);
  cursor: pointer;
}
.nav-toggle svg { width: 18px; height: 18px; }

/* ---------------------------------------------- 布局 */
.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: var(--sp-x2) var(--sp-5) var(--sp-x8);
}

.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 292px;
  gap: var(--sp-x1);
  align-items: start;
}

.layout.no-side { grid-template-columns: minmax(0, 1fr); max-width: 880px; margin: 0 auto; }

/* ---------------------------------------------- 首页大标题 */
.banner {
  position: relative;
  margin: var(--sp-1-5) 0 var(--sp-x2);
  padding: var(--sp-x4) var(--sp-x1) var(--sp-8);
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(255, 45, 120, .10), rgba(168, 85, 247, .05) 55%, transparent),
    var(--bg-soft);
  box-shadow: inset 0 0 60px rgba(255, 45, 120, .07), 0 0 0 1px rgba(255, 45, 120, .05);
}
.banner::before,
.banner::after {
  content: '';
  position: absolute;
  width: 120px; height: 120px;
  background-repeat: no-repeat;
  opacity: .5;
  pointer-events: none;
}
.banner::before {
  top: -6px; left: -6px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cg fill='none' stroke='%23ff2d78' stroke-opacity='0.5' stroke-width='1.1'%3E%3Cpath d='M2 60a58 58 0 0 1 58-58M2 92a90 90 0 0 1 90-90M2 118A116 116 0 0 1 118 2'/%3E%3C/g%3E%3C/svg%3E");
}
.banner::after {
  bottom: -6px; right: -6px;
  transform: rotate(180deg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cg fill='none' stroke='%23ff2d78' stroke-opacity='0.5' stroke-width='1.1'%3E%3Cpath d='M2 60a58 58 0 0 1 58-58M2 92a90 90 0 0 1 90-90M2 118A116 116 0 0 1 118 2'/%3E%3C/g%3E%3C/svg%3E");
}

.banner h1 {
  margin: 0;
  font-family: var(--font-head);
  font-size: clamp(28px, 5vw, 46px);
  font-weight: 700;
  letter-spacing: .08em;
  color: #fff;
  text-shadow: 0 0 10px rgba(255, 45, 120, .55), 0 0 34px rgba(168, 85, 247, .35);
  position: relative;
}
.banner h1.glitch::before,
.banner h1.glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.banner h1.glitch::before {
  color: var(--pink);
  animation: glitch-a 3.4s steps(1) infinite;
  clip-path: inset(0 0 62% 0);
}
.banner h1.glitch::after {
  color: var(--purple);
  animation: glitch-b 2.9s steps(1) infinite;
  clip-path: inset(58% 0 0 0);
}
@keyframes glitch-a {
  0%, 86%, 100% { transform: translate(0); opacity: 0; }
  87% { transform: translate(-3px, -2px); opacity: .85; }
  90% { transform: translate(2px, 1px); opacity: .6; }
  93% { transform: translate(-1px, 0); opacity: .4; }
}
@keyframes glitch-b {
  0%, 80%, 100% { transform: translate(0); opacity: 0; }
  82% { transform: translate(3px, 2px); opacity: .8; }
  85% { transform: translate(-2px, -1px); opacity: .5; }
  88% { transform: translate(1px, 1px); opacity: .35; }
}

.banner .banner-motto {
  margin: var(--sp-4) auto 0;
  max-width: 620px;
  font-size: var(--fs-sm);
  color: var(--text-dim);
  letter-spacing: .1em;
}
.banner .banner-rule {
  margin: var(--sp-5) auto 0;
  width: 190px; height: 14px;
  background-repeat: no-repeat;
  background-position: center;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='190' height='14'%3E%3Cg stroke='%23ff2d78' stroke-opacity='0.6' stroke-width='1'%3E%3Cpath d='M0 7h74M116 7h74'/%3E%3C/g%3E%3Cpath d='M95 2.4c1.8 2.4 4.4 3.9 4.4 6.1a4.4 4.4 0 0 1-8.8 0c0-2.2 2.6-3.7 4.4-6.1z' fill='%23ff2d78' fill-opacity='0.85'/%3E%3C/svg%3E");
}

/* ---------------------------------------------- 卡片 */
.card {
  position: relative;
  margin-bottom: var(--sp-6);
  padding: var(--sp-6-5) 28px;
  background: linear-gradient(180deg, var(--bg-card), var(--bg-soft));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .5);
  transition: border-color var(--dur-2) var(--ease-std), box-shadow var(--dur-2) var(--ease-std), transform var(--dur-2) var(--ease-std);
  overflow: hidden;
}
.card::before {
  /* 左侧霓虹竖条 */
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--pink), var(--purple), transparent);
  opacity: .45;
  transition: opacity var(--dur-2) var(--ease-std);
}
.card:hover {
  border-color: var(--line-pink);
  box-shadow: 0 0 0 1px rgba(255, 45, 120, .18), 0 0 28px rgba(255, 45, 120, .16), 0 14px 40px rgba(0, 0, 0, .6);
  transform: translateY(-2px);
}
.card:hover::before { opacity: 1; }

/* 文章是稳定的阅读纸面，不随鼠标靠近而移动整页。 */
.card.post, .card.post:hover {
  transform: none;
  border-color: var(--line);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .38);
}
.card.post::before, .card.post:hover::before { opacity: .28; }

.card-title {
  margin: 0 0 var(--sp-1-5);
  font-family: var(--font-head);
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: .03em;
  line-height: var(--lh-tight);
}
.card-title a { color: var(--text); }
.card-title a:hover { color: #fff; text-shadow: var(--glow-pink); }

.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3-5);
  margin: var(--sp-2-5) 0 var(--sp-3-5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  letter-spacing: .08em;
}
.card-meta .m {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-h1);
}
.card-meta .ico { width: 12px; height: 12px; color: var(--pink); opacity: .7; }
.card-meta a { color: var(--text-dim); }
.card-meta a:hover { color: var(--pink); }

.card-excerpt {
  color: var(--text-dim);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  word-break: break-word;
}
.card-excerpt p { margin: 0 0 var(--sp-2-5); }
.card-excerpt img { display: none; }

.card-more {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1-5);
  margin-top: var(--sp-1-5);
  font-size: var(--fs-sm);
  font-family: var(--font-mono);
  letter-spacing: .1em;
  color: var(--pink);
}
.card-more::after { content: '›'; transition: transform var(--dur-1) var(--ease-std); }
.card-more:hover::after { transform: translateX(3px); }

/* 标签胶囊 */
.tag-list { display: flex; flex-wrap: wrap; gap: var(--sp-h2); margin-top: var(--sp-3-5); }
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-h1);
  padding: 3px var(--sp-h4);
  font-size: var(--fs-xs);
  font-family: var(--font-mono);
  letter-spacing: .06em;
  color: var(--pink-soft);
  background: rgba(255, 45, 120, .07);
  border: 1px solid rgba(255, 45, 120, .28);
  border-radius: 999px;
  transition: all var(--dur-1) var(--ease-std);
}
.tag-chip:hover {
  color: #fff;
  background: rgba(255, 45, 120, .22);
  border-color: var(--pink);
  box-shadow: var(--glow-soft);
}
.tag-chip .count { color: var(--text-faint); font-size: var(--fs-xs); }

/* ---------------------------------------------- 文章正文 */
.post-head {
  margin: 0 0 var(--sp-6-5);
  padding-bottom: var(--sp-5);
  border-bottom: 1px dashed var(--line);
}
.post-head h1 {
  margin: 0 0 var(--sp-3-5);
  font-family: var(--font-head);
  font-size: clamp(23px, 3.4vw, 31px);
  line-height: var(--lh-tight);
  letter-spacing: .03em;
  color: #fff;
  text-shadow: 0 0 14px rgba(255, 45, 120, .3);
}

.post-body {
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  color: #ded3e2;
  word-break: break-word;
  text-wrap: pretty;
}
.post-body :is(h2, h3, h4) { scroll-margin-top: 96px; }
.post-body > :is(p, ul, ol, blockquote) { max-width: 72ch; }
.post-body > *:first-child { margin-top: 0; }

.post-body h1, .post-body h2, .post-body h3, .post-body h4, .post-body h5, .post-body h6 {
  font-family: var(--font-head);
  color: #fff;
  letter-spacing: .04em;
  margin: var(--sp-x3) 0 var(--sp-4);
  line-height: var(--lh-tight);
}
.post-body h2 {
  position: relative;
  padding-left: var(--sp-5);
  font-size: var(--fs-xl);
}
.post-body h2::before {
  content: '';
  position: absolute;
  left: 0; top: .42em;
  width: 8px; height: 8px;
  background: var(--pink);
  transform: rotate(45deg);
  box-shadow: var(--glow-pink);
}
.post-body h3 {
  font-size: var(--fs-lg);
  padding-left: var(--sp-4);
  border-left: 3px solid var(--pink);
}
.post-body h4 { font-size: var(--fs-md); color: var(--pink-soft); }

.post-body p { margin: 0 0 var(--sp-4-5); }

.post-body strong { color: #fff; text-shadow: 0 0 8px rgba(255, 45, 120, .3); }
.post-body em { color: var(--pink-soft); font-style: normal; }

.post-body a {
  color: var(--pink-soft);
  border-bottom: 1px dashed rgba(255, 122, 184, .5);
}
.post-body a:hover { color: #fff; border-bottom-color: var(--pink); }

.post-body ul, .post-body ol { padding-left: var(--sp-6); margin: 0 0 var(--sp-4-5); }
.post-body li { margin: var(--sp-1-5) 0; }
.post-body ul li::marker { color: var(--pink); content: '◆ '; font-size: var(--fs-xs); }
.post-body ol li::marker { color: var(--pink); font-family: var(--font-mono); }

.post-body blockquote {
  margin: var(--sp-5-5) 0;
  padding: var(--sp-3-5) var(--sp-5);
  background: linear-gradient(90deg, rgba(255, 45, 120, .09), transparent);
  border-left: 3px solid var(--pink);
  border-radius: 0 3px 3px 0;
  color: var(--text-dim);
  font-style: normal;
}
.post-body blockquote p:last-child { margin-bottom: 0; }

.post-body code {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  padding: var(--sp-0-5) var(--sp-h2);
  color: var(--pink-soft);
  background: rgba(255, 45, 120, .10);
  border: 1px solid rgba(255, 45, 120, .22);
  border-radius: 6px;
}

.post-body pre {
  margin: var(--sp-5-5) 0;
  padding: var(--sp-4-5) var(--sp-5);
  overflow-x: auto;
  background: #0b070e;
  border: 1px solid var(--line);
  border-left: 3px solid var(--pink);
  border-radius: 10px;
  box-shadow: inset 0 0 30px rgba(255, 45, 120, .05);
  line-height: var(--lh-snug);
}
.post-body pre code {
  padding: 0;
  background: none;
  border: 0;
  color: #e6dcea;
  font-size: var(--fs-sm);
}

.post-body img {
  display: block;
  margin: var(--sp-5) auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 0 0 1px rgba(255, 45, 120, .12), 0 14px 36px rgba(0, 0, 0, .6);
}

.post-body table {
  width: 100%;
  margin: var(--sp-5-5) 0;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}
.post-body th, .post-body td {
  padding: var(--sp-h3) var(--sp-h5);
  border: 1px solid var(--line);
  text-align: left;
}
.post-body th {
  background: rgba(255, 45, 120, .10);
  color: #fff;
  font-family: var(--font-head);
  letter-spacing: .04em;
}
.post-body tr:nth-child(even) td { background: rgba(255, 255, 255, .015); }

/* 只在有未完成阅读记录时出现，不占用浮动工具栏。 */
.reading-resume {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 16px;
  margin: 0 0 22px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--pink-dim, #a64b75);
  background: rgba(255, 122, 184, .025);
  border-radius: 3px;
}
.reading-resume[hidden] { display: none; }
.reading-resume p { margin: 0; color: var(--text-mute); font-size: var(--fs-xs); letter-spacing: .04em; }
.reading-resume b { color: var(--text-head); font-family: var(--font-mono); font-weight: 400; }
.reading-resume-actions { display: flex; align-items: center; gap: 6px; }
.reading-resume button { min-height: 44px; padding: 8px 10px; border: 0; border-radius: 2px; background: transparent; color: var(--pink); font: inherit; font-size: var(--fs-xs); cursor: pointer; transition: background-color .16s ease, color .16s ease; }
.reading-resume [data-reading-clear] { color: var(--text-mute); }
.reading-resume button:hover, .reading-resume button:focus-visible { background: rgba(255, 122, 184, .08); color: #fff; }
.reading-resume button:active { background: rgba(255, 122, 184, .14); }
@media (max-width: 720px) {
  .reading-resume { padding: 8px 10px; gap: 0 8px; }
  .reading-resume-actions { gap: 0; }
  .reading-resume button { padding: 8px; }
}

/* 文章目录 */
.toc-box {
  margin: 0 0 var(--sp-6-5);
  padding: 0;
  background: linear-gradient(180deg, rgba(255, 45, 120, .06), transparent);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
}
.toc-box > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4-5);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--pink);
  list-style: none;
  transition: background-color .16s ease, color .16s ease;
}
.toc-box > summary:hover { color: #fff; background-color: rgba(255, 45, 120, .045); }
.toc-box[open] .toc-inner { animation: page-in .18s ease both; }
.toc-box > summary::-webkit-details-marker { display: none; }
.toc-box > summary .ico { width: 13px; height: 13px; flex: none; }
.toc-box > summary::after {
  content: '＋';
  margin-left: auto;
  font-size: var(--fs-xs);
  color: var(--text-faint);
}
.toc-box[open] > summary::after { content: '－'; }
.toc-inner {
  padding: var(--sp-1) var(--sp-4-5) var(--sp-4);
  border-top: 1px dashed var(--line);
  max-height: 46vh;
  overflow-y: auto;
}
.toc-inner .toc { margin: 0; padding-left: 0; list-style: none; counter-reset: toc; }
.toc-inner .toc-item { position: relative; margin: 2px 0; padding-left: 18px; }
.toc-inner .toc-item::before {
  counter-increment: toc;
  content: '◆';
  position: absolute;
  left: 0;
  top: 15px;
  width: 14px;
  font-size: var(--fs-2xs);
  color: var(--pink);
  opacity: .7;
}
.toc-inner .toc-link { display: block; min-height: 44px; padding: 10px 8px; border-radius: 2px; color: var(--text-dim); font-size: var(--fs-sm); line-height: 1.6; overflow-wrap: anywhere; transition: color .16s ease, background-color .16s ease; }
.toc-inner .toc-link:hover, .toc-inner .toc-link:focus-visible { color: #fff; background-color: rgba(255, 122, 184, .06); }
.toc-inner .toc-child { padding-left: var(--sp-4); list-style: none; }
.toc-inner .toc-child .toc-link { font-size: var(--fs-sm); color: var(--text-faint); }
.toc-inner .toc-number { display: none; }

/* 正文首字下沉（仅中文长文效果更好，谨慎开启） */
.post-body .dropcap::first-letter {
  font-family: var(--font-head);
  font-size: 2.6em;
  line-height: 1;
  float: left;
  margin: var(--sp-1-5) var(--sp-2-5) 0 0;
  color: var(--pink);
  text-shadow: var(--glow-pink);
}

/* 文章底部 */
.post-foot {
  margin-top: var(--sp-x2);
  padding-top: var(--sp-5-5);
  border-top: 1px dashed var(--line);
}
.post-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3-5);
  margin-top: var(--sp-5);
}
.post-nav.is-single { grid-template-columns: minmax(0, 1fr); }
.post-nav a {
  display: block;
  padding: var(--sp-h5) var(--sp-4);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: var(--fs-sm);
  color: var(--text-dim);
  line-height: var(--lh-snug);
  transition: border-color .18s ease, background-color .18s ease, color .18s ease, transform .1s ease;
}
.post-nav a:hover {
  border-color: var(--line-pink);
  color: #fff;
  box-shadow: 0 0 18px rgba(255, 45, 120, .16);
  text-shadow: none;
}
.post-nav .dir {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .16em;
  color: var(--pink);
  margin-bottom: var(--sp-h1);
  text-transform: uppercase;
}
.post-nav .dir .ico { width: 14px; height: 14px; flex: none; }
.post-nav .next .dir { justify-content: flex-end; }
.post-nav-title { display: block; color: var(--text-head); font-family: var(--font-head); font-size: 15px; line-height: 1.65; overflow-wrap: anywhere; }
.post-nav .next { text-align: right; }

.collection-back { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; margin: 0 0 12px; color: var(--text-dim); font-size: 12px; letter-spacing: .04em; }
.collection-back:hover { color: var(--pink-soft); text-shadow: none; }

/* ---------------------------------------------- 侧边栏 */
.side { position: sticky; top: calc(var(--nav-h) + 18px); }
.widget {
  position: relative;
  margin-bottom: var(--sp-5);
  padding: var(--sp-5) var(--sp-5) var(--sp-5-5);
  background: linear-gradient(180deg, var(--bg-card), var(--bg-soft));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .45);
}
.widget-title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-4);
  padding-bottom: var(--sp-h4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--pink);
  border-bottom: 1px solid var(--line);
}
.widget-title .ico { width: 13px; height: 13px; }
.widget-title::after {
  content: '';
  margin-left: auto;
  width: 6px; height: 6px;
  background: var(--pink);
  transform: rotate(45deg);
  box-shadow: var(--glow-pink);
}

/* 侧栏个人卡 */
.profile { text-align: center; }
.profile .avatar {
  width: 82px; height: 82px;
  margin: 0 auto var(--sp-3-5);
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--pink);
  box-shadow: 0 0 0 4px rgba(255, 45, 120, .12), 0 0 22px rgba(255, 45, 120, .45);
}
.profile .avatar-fallback {
  width: 82px; height: 82px;
  margin: 0 auto var(--sp-3-5);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 2px solid var(--pink);
  background: radial-gradient(circle at 35% 30%, rgba(255, 45, 120, .35), rgba(168, 85, 247, .18));
  box-shadow: 0 0 22px rgba(255, 45, 120, .45);
  color: #fff;
  font-family: var(--font-head);
  font-size: var(--fs-2xl);
}
.profile .name {
  font-family: var(--font-head);
  font-size: var(--fs-lg);
  color: #fff;
  letter-spacing: .08em;
}
.profile .motto {
  margin-top: var(--sp-h3);
  font-size: var(--fs-sm);
  color: var(--text-faint);
  line-height: var(--lh-snug);
}
.profile .motto::before { content: '“'; color: var(--pink); }
.profile .motto::after { content: '”'; color: var(--pink); }

.profile-stats {
  display: flex;
  margin-top: var(--sp-4);
  padding-top: var(--sp-3-5);
  border-top: 1px dashed var(--line);
}
.profile-stats div { flex: 1; }
.profile-stats .n {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-lg);
  color: var(--pink);
  text-shadow: var(--glow-pink);
}
.profile-stats .l {
  font-size: var(--fs-xs);
  letter-spacing: .12em;
  color: var(--text-faint);
}

/* 侧栏列表 */
.widget-list { list-style: none; margin: 0; padding: 0; }
.widget-list li {
  display: flex;
  align-items: baseline;
  gap: var(--sp-h3);
  padding: var(--sp-h2) 0;
  font-size: var(--fs-sm);
  border-bottom: 1px dashed rgba(46, 32, 51, .8);
}
.widget-list li:last-child { border-bottom: 0; }
.widget-list li::before {
  content: '♥';
  flex: none;
  font-size: var(--fs-2xs);
  color: var(--pink);
  opacity: .75;
}
.widget-list a { color: var(--text-dim); }
.widget-list a:hover { color: #fff; }
.widget-list .n {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-faint);
}

/* 云标签 */
.tag-cloud { display: flex; flex-wrap: wrap; gap: var(--sp-h2); }
.tag-cloud a {
  padding: 3px var(--sp-2-5);
  font-size: var(--fs-xs);
  color: var(--text-dim);
  background: rgba(255, 255, 255, .025);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.tag-cloud a:hover {
  color: #fff;
  border-color: var(--pink);
  background: rgba(255, 45, 120, .16);
  box-shadow: var(--glow-soft);
  text-shadow: none;
}

/* ---------------------------------------------- 归档 / 列表页 */
.page-title {
  margin: 0 0 var(--sp-6-5);
  font-family: var(--font-head);
  font-size: clamp(22px, 3.2vw, 29px);
  color: #fff;
  letter-spacing: .06em;
  text-align: center;
  text-shadow: 0 0 14px rgba(255, 45, 120, .35);
}
.page-title .sub {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--text-faint);
  text-shadow: none;
}

.year-group { margin-bottom: var(--sp-2); }
.year-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3-5);
  margin: var(--sp-x1) 0 var(--sp-3-5);
  font-family: var(--font-mono);
  font-size: var(--fs-xl);
  color: var(--pink);
  letter-spacing: .1em;
  text-shadow: var(--glow-pink);
}
.year-head::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--line-pink), transparent);
}

.arch-list { list-style: none; margin: 0; padding: 0; }
.arch-list li {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding: var(--sp-h4) var(--sp-1);
  border-bottom: 1px dashed rgba(46, 32, 51, .75);
}
.arch-list li:hover { background: rgba(255, 45, 120, .04); }
.arch-list a { color: var(--text); font-size: var(--fs-base); }
.arch-list a:hover { color: #fff; text-shadow: var(--glow-pink); }
.arch-list time {
  margin-left: auto;
  flex: none;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  letter-spacing: .06em;
}

/* 分类 / 标签总览网格 */
.term-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--sp-3-5);
}
.term {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-4-5);
  background: linear-gradient(180deg, var(--bg-card), var(--bg-soft));
  border: 1px solid var(--line);
  border-radius: 12px;
  transition: all var(--dur-1) var(--ease-std);
  overflow: hidden;
}
.term::after {
  content: '';
  position: absolute;
  right: -18px; bottom: -18px;
  width: 52px; height: 52px;
  border: 1px solid var(--line-pink);
  border-radius: 50%;
  opacity: .5;
}
.term:hover {
  border-color: var(--line-pink);
  box-shadow: 0 0 22px rgba(255, 45, 120, .18);
  transform: translateY(-2px);
}
.term .term-name {
  font-size: var(--fs-base);
  color: var(--text);
  font-family: var(--font-head);
  letter-spacing: .04em;
}
.term:hover .term-name { color: #fff; text-shadow: var(--glow-pink); }
.term .term-count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--pink);
  z-index: 1;
}

/* 分页 */
.pager {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--sp-h2);
  margin: var(--sp-x2) 0 var(--sp-1-5);
}
.pager a, .pager span {
  min-width: 36px;
  height: 36px;
  padding: 0 var(--sp-h4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  transition: all var(--dur-1) var(--ease-std);
}
.pager a:hover {
  color: #fff;
  border-color: var(--pink);
  box-shadow: var(--glow-soft);
  text-shadow: none;
}
.pager .current {
  color: #fff;
  background: linear-gradient(180deg, rgba(255, 45, 120, .3), rgba(168, 85, 247, .18));
  border-color: var(--pink);
  box-shadow: var(--glow-soft);
}
.pager .space { border: 0; background: none; }

/* ---------------------------------------------- 页脚 */
.footer {
  position: relative;
  margin-top: var(--sp-5);
  padding: var(--sp-8) var(--sp-5) var(--sp-x5);
  text-align: center;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 45, 120, .05), transparent 60%);
  font-size: var(--fs-sm);
  color: var(--text-faint);
  letter-spacing: .05em;
}
.footer::before {
  /* 页脚蕾丝 */
  content: '';
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 12px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='12'%3E%3Cpath d='M0 12h24V9.6c-1.6 0-3-1.4-3-3.2S22.4 3.2 24 3.2V0H0v3.2c1.6 0 3 1.4 3 3.2S1.6 9.6 0 9.6z' fill='%23ff2d78' fill-opacity='0.13'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  background-size: 24px 12px;
  opacity: .9;
}
body.no-lace .footer::before { display: none; }

.footer .foot-mark {
  width: 20px; height: 20px;
  margin: 0 auto var(--sp-3);
  color: var(--pink);
  opacity: .85;
  filter: drop-shadow(0 0 6px rgba(255, 45, 120, .7));
}
.footer a { color: var(--text-dim); }
.footer a:hover { color: var(--pink); text-shadow: var(--glow-pink); }
.footer .theme-name { color: var(--pink-soft); }
.footer .foot-sep { margin: 0 var(--sp-2); color: var(--line); }

/* 回到顶部 */
.to-top {
  position: fixed;
  right: 22px; bottom: 24px;
  z-index: 950;
  width: 44px; height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(20, 13, 23, .9);
  border: 1px solid var(--line-pink);
  border-radius: 50%;
  color: var(--pink);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: all var(--dur-2) var(--ease-std);
  backdrop-filter: blur(8px);
}
.to-top svg { width: 17px; height: 17px; flex: none; }
.to-top.show { opacity: 1; visibility: visible; transform: translateY(0); }
.to-top:hover { box-shadow: 0 0 20px rgba(255, 45, 120, .5); color: #fff; }

/* 阅读进度条 */
.progress {
  position: fixed;
  top: 0; left: 0;
  z-index: 999;
  height: 2px;
  width: 0;
  background: linear-gradient(90deg, var(--pink), var(--purple));
  box-shadow: 0 0 10px rgba(255, 45, 120, .8);
}

/* 鼠标粉色拖尾 */

/* 图片以原生模态框预览，页面与焦点在关闭后回到原位。 */
.lb-mask { position: fixed; inset: 0; z-index: 10010; width: 100%; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 64px 24px 44px; border: 0; background: rgba(6, 3, 9, .96); color: var(--text); overflow: hidden; }
.lb-mask[open] { display: grid; place-items: center; animation: image-preview-in .2s var(--ease-out) both; }
.lb-mask::backdrop { background: rgba(4, 2, 5, .6); }
.lb-mask img { display: block; max-width: 100%; max-height: calc(100dvh - 120px); width: auto; height: auto; border-radius: 3px; object-fit: contain; box-shadow: 0 12px 50px rgba(0, 0, 0, .35); }
.lb-close { position: absolute; top: max(16px, env(safe-area-inset-top, 0px)); right: max(20px, env(safe-area-inset-right, 0px)); display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 1px solid var(--line); border-radius: 3px; background: rgba(24, 15, 30, .8); color: var(--text); font: 28px/1 sans-serif; cursor: pointer; transition: background-color .16s ease, border-color .16s ease, transform .1s ease; }
.lb-close:hover { background-color: rgba(255, 45, 120, .12); border-color: var(--pink-soft); }
.lb-close:active { transform: scale(.96); }
.lb-hint { position: absolute; left: 20px; right: 20px; bottom: max(16px, env(safe-area-inset-bottom, 0px)); text-align: center; color: var(--text-dim); font-size: 11px; letter-spacing: .06em; pointer-events: none; }
.lb-mask.is-closing { animation: page-out .14s ease both; }
@keyframes image-preview-in { from { opacity: 0; transform: scale(.99); } to { opacity: 1; transform: none; } }
.spark {
  position: fixed;
  z-index: 9997;
  width: 7px; height: 7px;
  pointer-events: none;
  background: var(--pink);
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  animation: spark-fade var(--dur-3) var(--ease-out) forwards;
}
@keyframes spark-fade {
  from { opacity: .85; transform: scale(1) rotate(0deg); }
  to { opacity: 0; transform: scale(.2) rotate(140deg) translateY(10px); }
}

/* 空状态 */
.empty {
  padding: var(--sp-x6) var(--sp-5);
  text-align: center;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  letter-spacing: .1em;
}

/* ---------------------------------------------- 响应式 */
@media (max-width: 980px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .side { position: static; }
  .nav-links {
    position: fixed;
    top: var(--nav-h);
    left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--sp-2-5) var(--sp-4) var(--sp-4-5);
    background: rgba(8, 5, 10, .97);
    border-bottom: 1px solid var(--line-pink);
    box-shadow: 0 20px 40px rgba(0, 0, 0, .7);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: transform .22s var(--ease-out), opacity .18s ease, visibility 0s .22s;
  }
  .nav-links.open { transform: translateY(0); opacity: 1; visibility: visible; pointer-events: auto; transition-delay: 0s; }
  .nav-links a { border-radius: 3px; padding: var(--sp-h4) var(--sp-3-5); min-height: 44px; }
  .nav-toggle { display: flex; flex-shrink: 0; }
  .nav-inner { gap: 12px; }
  .brand { min-width: 0; gap: 8px; }
  .brand .brand-text { min-width: 0; font-size: clamp(13px, 4vw, 18px); overflow: hidden; text-overflow: ellipsis; }
  .brand .brand-sub { display: none; }
}

@media (max-width: 720px) {
  body { font-size: var(--fs-base); }
  .banner h1 { font-size: var(--fs-2xl); letter-spacing: .03em; }
  .wrap { padding: var(--sp-6) var(--sp-h6) var(--sp-x6); }
  .card { padding: var(--sp-5) var(--sp-4-5); }
  .banner { padding: var(--sp-7) var(--sp-4-5) 28px; }
  .post-nav { grid-template-columns: 1fr; }
  .post-nav .next { text-align: left; }
  .post-nav .next .dir { justify-content: flex-start; }
  .card.post { padding: 24px 16px 28px; }
  .wrap:has(.card.post) { padding-left: 12px; padding-right: 12px; }
  .post-body p { margin-bottom: 1.35em; }
  .post-nav a { padding: 16px; }
  .to-top { right: 14px; bottom: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
}

/* ===== jirai-deco.css ===== */
/* ============================================================
   jirai-deco — 地雷系装饰层
   医疗十字光标 / 跑马灯缎带 / 阅读 HUD / 拍立得相框 /
   终端代码块 / 引用框 / 幕布分隔 / 吐司提示
   ============================================================ */

/* ---------------------------------------------- 跑马灯缎带 */
.ribbon {
  position: relative;
  z-index: 880;
  height: 24px;
  overflow: hidden;
  background:
    repeating-linear-gradient(45deg, rgba(255, 45, 120, .16) 0 8px, rgba(0, 0, 0, 0) 8px 16px),
    linear-gradient(180deg, rgba(255, 45, 120, .16), rgba(168, 85, 247, .10));
  border-bottom: 1px solid rgba(255, 45, 120, .28);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45), inset 0 0 18px rgba(255, 45, 120, .10);
  display: flex;
  align-items: center;
}
.ribbon-track {
  display: flex;
  width: 100%;
  justify-content: center;
  white-space: nowrap;
  animation: none;
}
.ribbon:hover .ribbon-track { animation-play-state: paused; }
.ribbon-run {
  flex: none;
  padding-right: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .22em;
  color: var(--pink-soft);
  text-shadow: 0 0 8px rgba(255, 45, 120, .55);
}
@keyframes ribbon-run {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ---------------------------------------------- 光环光晕层 */
.halo-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.halo-layer i {
  position: absolute;
  top: -18vh; left: 50%;
  width: 140vw; height: 60vh;
  margin-left: -70vw;
  background:
    radial-gradient(closest-side, rgba(255, 45, 120, .18), transparent 70%),
    radial-gradient(closest-side, rgba(168, 85, 247, .14), transparent 72%);
  filter: blur(34px);
  animation: halo-drift 16s var(--ease-std) infinite alternate;
}
@keyframes halo-drift {
  from { transform: translateX(-6%) scale(1); opacity: .75; }
  to   { transform: translateX(6%) scale(1.12); opacity: 1; }
}
/* 内容层压在光环之上 */
.wrap, .footer, .ribbon { position: relative; z-index: 2; }
.ribbon { z-index: 880; }

/* ---------------------------------------------- 幕布分隔 */
.curtain {
  display: flex;
  align-items: center;
  gap: var(--sp-3-5);
  margin: var(--sp-1) 0 var(--sp-6-5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .42em;
  color: rgba(255, 122, 184, .75);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
}
.curtain-line {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 45, 120, .5), transparent);
  position: relative;
}
.curtain-line::after {
  content: '';
  position: absolute;
  top: -2.5px;
  width: 6px; height: 6px;
  background: var(--pink);
  transform: rotate(45deg);
  box-shadow: var(--glow-pink);
}
.curtain-line:first-child::after { right: 0; }
.curtain-line:last-child::after { left: 0; }
.curtain-text { flex: none; text-shadow: 0 0 10px rgba(255, 45, 120, .4); }

/* 卡片之间的装饰符 */
.deco { display: none; }

/* ---------------------------------------------- 阅读 HUD */
.hud {
  position: fixed;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 900;
  width: 34px;
  padding: var(--sp-2-5) 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-h3);
  background: rgba(14, 8, 17, .72);
  border: 1px solid var(--line);
  border-radius: 999px;
  backdrop-filter: blur(8px);
  box-shadow: 0 0 22px rgba(0, 0, 0, .5), inset 0 0 12px rgba(255, 45, 120, .06);
  pointer-events: none;
  transition: opacity var(--dur-2) var(--ease-std);
}
.hud-line {
  width: 1px; height: 16px;
  background: linear-gradient(180deg, transparent, var(--line-pink), transparent);
}
.hud-pct {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--pink);
  text-shadow: var(--glow-pink);
  letter-spacing: 0;
}
.hud-pct em { font-style: normal; font-size: var(--fs-3xs); opacity: .7; }
.hud-vert {
  writing-mode: vertical-rl;
  font-size: var(--fs-2xs);
  letter-spacing: .3em;
  color: var(--text-faint);
}
.hud-bar {
  position: relative;
  width: 3px;
  height: 90px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .07);
  overflow: hidden;
}
.hud-bar i {
  position: absolute;
  left: 0; bottom: 0;
  width: 100%;
  height: 0;
  background: linear-gradient(180deg, var(--pink), var(--purple));
  box-shadow: 0 0 8px rgba(255, 45, 120, .8);
  transition: height var(--dur-1) var(--ease-loop);
}

/* ---------------------------------------------- 吐司提示 */
.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: var(--sp-2-5);
  max-width: min(90vw, 460px);
  padding: var(--sp-h5) var(--sp-4) var(--sp-h6);
  transform: translate(-50%, 18px);
  opacity: 0;
  visibility: hidden;
  background: linear-gradient(180deg, rgba(27, 18, 32, .97), rgba(14, 8, 17, .97));
  border: 1px solid var(--line-pink);
  border-radius: 12px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .7), 0 0 26px rgba(255, 45, 120, .22);
  font-size: var(--fs-sm);
  color: var(--text);
  overflow: hidden;
  transition: opacity var(--dur-3) var(--ease-std), transform var(--dur-3) cubic-bezier(.2, .8, .3, 1.1), visibility var(--dur-3);
}
.toast.show { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.toast .ico { width: 15px; height: 15px; color: var(--pink); flex: none; }
.toast-text { line-height: var(--lh-snug); }
.toast-x {
  flex: none;
  margin-left: var(--sp-0-5);
  width: 22px; height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--text-faint);
  cursor: pointer;
}
.toast-x:hover { color: #fff; border-color: var(--pink); }
.toast-x .ico { width: 11px; height: 11px; }
.toast-timer {
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  width: 100%;
  transform-origin: left;
  background: linear-gradient(90deg, var(--pink), var(--purple));
  animation: toast-run 7.5s var(--ease-loop) forwards;
}
@keyframes toast-run { from { transform: scaleX(1); } to { transform: scaleX(0); } }

/* ---------------------------------------------- 医疗十字光标 */
.med-cursor {
  position: fixed;
  left: 0; top: 0;
  z-index: 9996;
  width: 34px; height: 34px;
  margin: var(--offset-deco-sm) 0 0 var(--offset-deco-sm);
  color: var(--pink);
  opacity: 0;
  pointer-events: none;
  filter: drop-shadow(0 0 7px rgba(255, 45, 120, .85));
  transition: opacity var(--dur-2) var(--ease-std), transform var(--dur-1) var(--ease-std);
  will-change: transform;
}
.med-cursor.on { opacity: .9; }
.med-cursor.hot { transform: scale(1.45) rotate(90deg); color: #fff; }
.med-cursor svg { width: 100%; height: 100%; animation: med-spin 9s var(--ease-loop) infinite; }
@keyframes med-spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------- 正文：标题角标 */
.post-body h2.has-num,
.post-body h3.has-num,
.post-body h4.has-num { position: relative; }

.post-body h2.has-num { padding-left: var(--sp-x7); }
.post-body h2.has-num::before {
  content: attr(data-num);
  position: absolute;
  left: 0; top: .30em;
  width: 34px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-align: center;
  color: var(--pink);
  background: rgba(255, 45, 120, .10);
  border: 1px solid var(--line-pink);
  border-radius: 6px;
  padding: var(--sp-0-5) 0;
  transform: none;
  box-shadow: 0 0 12px rgba(255, 45, 120, .18);
  text-shadow: var(--glow-pink);
}
/* 编号后面的小菱形分隔 */
.post-body h2.has-num::after {
  content: '';
  position: absolute;
  left: 42px; top: .52em;
  width: 5px; height: 5px;
  background: var(--pink);
  transform: rotate(45deg);
  opacity: .75;
}
.post-body h3.has-num { padding-left: 33px; }
.post-body h3.has-num::after {
  content: attr(data-num);
  position: absolute;
  left: 0; top: .18em;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--pink-soft);
  letter-spacing: .04em;
  text-shadow: 0 0 8px rgba(255, 45, 120, .5);
}
.post-body h4.has-num { padding-left: var(--sp-x1); }
.post-body h4.has-num::after {
  content: attr(data-num);
  position: absolute;
  left: 0; top: .2em;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--text-faint);
}

/* ---------------------------------------------- 正文：引用框 */
.jirai-note {
  position: relative;
  margin: var(--sp-6) 0;
  padding: 0;
  background: linear-gradient(135deg, rgba(255, 45, 120, .10), rgba(168, 85, 247, .06));
  border: 1px solid var(--line);
  border-left: 3px solid var(--pink);
  border-radius: 0 12px 12px 0;
  color: var(--text-dim);
  font-style: normal;
  overflow: hidden;
}
.jirai-note::after {
  content: '';
  position: absolute;
  right: -16px; bottom: -16px;
  width: 56px; height: 56px;
  background:
    linear-gradient(currentColor, currentColor) center/18px 2px no-repeat,
    linear-gradient(currentColor, currentColor) center/2px 18px no-repeat;
  color: rgba(255, 45, 120, .35);
  transform: rotate(18deg);
}
.jn-head {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1-5);
  margin: 0 0 0 -3px;
  padding: var(--sp-h2) var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .2em;
  color: #fff;
  background: linear-gradient(90deg, rgba(255, 45, 120, .55), rgba(255, 45, 120, .12));
}
.jn-head::before { content: '†'; font-size: var(--fs-sm); }
.jn-body { padding: var(--sp-3-5) var(--sp-5) var(--sp-1); }
.jn-body p:last-child { margin-bottom: var(--sp-2-5); }
.jirai-note-warn { border-left-color: var(--warn); }
.jirai-note-warn .jn-head { background: linear-gradient(90deg, rgba(255, 176, 32, .55), rgba(255, 176, 32, .10)); }
.jirai-note-warn::after { color: rgba(255, 176, 32, .35); }
.jirai-note-danger { border-left-color: #ff2d2d; }
.jirai-note-danger .jn-head { background: linear-gradient(90deg, rgba(255, 45, 45, .6), rgba(255, 45, 45, .12)); }
.jirai-note-danger::after { color: rgba(255, 45, 45, .35); }
.jirai-note-note { border-left-color: var(--purple); }
.jirai-note-note .jn-head { background: linear-gradient(90deg, rgba(168, 85, 247, .5), rgba(168, 85, 247, .10)); }
.jirai-note-note::after { color: rgba(168, 85, 247, .35); }

/* ---------------------------------------------- 正文：终端代码块 */
.post-body figure.jirai-term {
  margin: var(--sp-6) 0;
  background: linear-gradient(180deg, #120b16, #09060b);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: inset 0 0 30px rgba(255, 45, 120, .05), 0 10px 26px rgba(0, 0, 0, .5);
}
.post-body figure.jirai-term .term-bar,
.post-body pre.jirai-term .term-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-1-5);
  padding: var(--sp-h3) var(--sp-3-5);
  background: rgba(255, 45, 120, .07);
  border-bottom: 1px solid var(--line);
}
.post-body figure.jirai-term .term-bar i,
.post-body pre.jirai-term .term-bar i {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .16);
}
.post-body figure.jirai-term .term-bar i:first-child,
.post-body pre.jirai-term .term-bar i:first-child { background: var(--pink); box-shadow: 0 0 8px rgba(255, 45, 120, .8); }
.post-body figure.jirai-term .term-bar i:nth-child(2),
.post-body pre.jirai-term .term-bar i:nth-child(2) { background: var(--purple); }
/* highlight.js 的行号表适配 */
.post-body figure.jirai-term table { margin: 0; font-size: var(--fs-sm); }
.post-body figure.jirai-term td { border: 0; padding: 0; background: none !important; }
.post-body figure.jirai-term td.gutter {
  width: 1%;
  padding: var(--sp-3-5) var(--sp-3) var(--sp-4) var(--sp-4);
  color: var(--text-faint);
  border-right: 1px solid var(--line);
  user-select: none;
  text-align: right;
  opacity: .6;
}
.post-body figure.jirai-term td.code { padding: var(--sp-3-5) var(--sp-4) var(--sp-4); }
.post-body figure.jirai-term pre { margin: 0; border: 0; background: none; box-shadow: none; border-radius: 0; }

.post-body pre.jirai-term {
  padding: 0 0 var(--sp-4);
  background: linear-gradient(180deg, #120b16, #09060b);
  border: 1px solid var(--line);
  border-left: 1px solid var(--line);
  border-radius: 12px;
}
.post-body pre.jirai-term .term-bar {
  margin-bottom: var(--sp-3-5);
  padding: var(--sp-h3) var(--sp-3-5);
}
.post-body pre.jirai-term code { display: block; padding: 0 var(--sp-4-5); }

/* ---------------------------------------------- 正文：拍立得相框 */
.post-body img.jirai-photo {
  padding: var(--sp-h3);
  background: linear-gradient(180deg, #fdf7fa, #efe2ea);
  border: 0;
  border-radius: 3px 3px 3px 3px;
  box-shadow:
    0 0 0 1px rgba(255, 45, 120, .28),
    0 12px 30px rgba(0, 0, 0, .65),
    0 0 34px rgba(255, 45, 120, .16);
  transform: rotate(-.5deg);
  transition: transform var(--dur-2) var(--ease-std), box-shadow var(--dur-2) var(--ease-std);
}
/* <picture> 会成为 <img> 的父元素，导致 img:nth-of-type(even) 永远选中第一张、
   交替倾斜失效。改为按 <picture> 计数。*/
.post-body picture { display: block; }
/* 交替倾斜：<picture> 已被解包为 #post-body 的直接子元素，
   因此这里的 :nth-of-type 能正确按顺序取奇偶。 */
.post-body picture:nth-of-type(odd) img.jirai-photo { transform: rotate(-.5deg); }
.post-body picture:nth-of-type(even) img.jirai-photo { transform: rotate(.6deg); }
/* 行内小图标/表情：图片后加 {.inline-ico} 即可取消相框与居中 */
.post-body img.jirai-photo.inline-ico {
  display: inline-block;
  width: auto;
  max-height: 1.35em;
  margin: 0 .25em;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  transform: none;
  vertical-align: -.28em;
}
.post-body img.jirai-photo:hover {
  transform: rotate(0deg) scale(1.012);
  box-shadow:
    0 0 0 1px rgba(255, 45, 120, .5),
    0 14px 36px rgba(0, 0, 0, .7),
    0 0 46px rgba(255, 45, 120, .3);
}

/* ---------------------------------------------- 卡片悬停星屑 */
.card:not(.post)::after {
  content: '';
  position: absolute;
  right: 14px; top: 14px;
  width: 0; height: 0;
  background: var(--pink);
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  opacity: 0;
  transition: all var(--dur-3) var(--ease-std);
  pointer-events: none;
}
.card:not(.post):hover::after {
  width: 14px; height: 14px;
  opacity: .9;
  box-shadow: 0 0 12px rgba(255, 45, 120, .9);
  animation: card-sparkle 1.4s var(--ease-std) infinite;
}
@keyframes card-sparkle {
  0%, 100% { transform: scale(1) rotate(0deg); }
  50% { transform: scale(1.35) rotate(72deg); }
}

/* ---------------------------------------------- 页尾心跳 */
.heart-beat {
  display: flex;
  justify-content: center;
  margin: var(--sp-x2) 0 var(--sp-1-5);
  color: var(--pink);
  opacity: .55;
}
.heart-beat .ico {
  width: 22px; height: 22px;
  filter: drop-shadow(0 0 8px rgba(255, 45, 120, .8));
  animation: heartbeat 2.4s var(--ease-std) infinite;
}
.heart-beat.reveal { animation: hb-reveal 1.4s var(--ease-out); }
@keyframes hb-reveal {
  0%   { transform: scale(.6); opacity: .2; }
  40%  { transform: scale(1.5); opacity: 1; }
  100% { transform: scale(1); opacity: .55; }
}

/* ---------------------------------------------- 导航 / 页脚小装饰 */
.nav-links a .ico { transition: transform var(--dur-1) var(--ease-std); }
.nav-links a:hover .ico { transform: scale(1.18) rotate(-8deg); }

.profile .avatar,
.profile .avatar-fallback { position: relative; }
.profile .avatar::after,
.profile .avatar-fallback::after { content: none; }

/* 档案卡四角十字 */
.widget::before,
.widget::after {
  color: rgba(255, 45, 120, .5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1;
  pointer-events: none;
}
.widget::before { content: '+'; position: absolute; left: 7px; top: 6px; }
.widget::after  { content: '+'; position: absolute; right: 7px; bottom: 6px; }

/* 标签胶囊加入绷带条纹 */
.tag-chip {
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255, 45, 120, .10) 0 5px,
    rgba(255, 45, 120, 0) 5px 10px
  );
}

/* ---------------------------------------------- 档案卡增强 */
.profile { position: relative; }
.room-tag {
  position: absolute;
  right: 12px;
  top: 17px;
  padding: var(--sp-0-5) var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .1em;
  color: var(--pink-soft);
  background: rgba(255, 45, 120, .1);
  border: 1px solid var(--line-pink);
  border-radius: 4px;
  z-index: 2;
  box-shadow: 0 0 10px rgba(255, 45, 120, .14);
}
.profile .widget-title { padding-right: var(--sp-x9); }

/* 心电线条 */
.pulse-line {
  margin: var(--sp-h6) 0 3px;
  height: 26px;
  opacity: .75;
}
.pulse-line svg { width: 100%; height: 100%; display: block; }
.pulse-line path {
  fill: none;
  stroke: var(--pink);
  stroke-width: 1.6;
  stroke-linejoin: round;
  stroke-linecap: round;
  filter: drop-shadow(0 0 5px rgba(255, 45, 120, .85));
  stroke-dasharray: 420;
  stroke-dashoffset: 420;
  animation: pulse-draw 5s var(--ease-loop) infinite;
}
@keyframes pulse-draw {
  0%        { stroke-dashoffset: 420; }
  62%, 100% { stroke-dashoffset: 0; }
}

.profile-foot {
  margin-top: var(--sp-h5);
  padding-top: var(--sp-h4);
  border-top: 1px dashed var(--line);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .12em;
  color: var(--text-faint);
}
.profile-foot .pf-sep { margin: 0 var(--sp-h2); color: var(--line-pink); }
.profile-updated {
  margin-top: var(--sp-h1);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .1em;
  color: rgba(255, 122, 184, .65);
}

/* 条形码 */
.barcode {
  height: 22px;
  margin: var(--sp-3-5) auto 0;
  width: 88%;
  opacity: .42;
  background-image: repeating-linear-gradient(
    90deg,
    #ece4ee 0 1px, transparent 1px 3px,
    #ece4ee 3px 5px, transparent 5px 6px,
    #ece4ee 6px 7px, transparent 7px 11px,
    #ece4ee 11px 14px, transparent 14px 15px,
    #ece4ee 15px 16px, transparent 16px 19px,
    #ece4ee 19px 22px, transparent 22px 24px,
    #ece4ee 24px 25px, transparent 25px 28px
  );
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

/* ---------------------------------------------- 角落十字框 */
.corner-mark {
  position: absolute;
  width: 9px; height: 9px;
  opacity: .34;
  pointer-events: none;
  color: var(--pink);
  transition: opacity var(--dur-2) var(--ease-std), color var(--dur-2) var(--ease-std);
}
.corner-mark::before,
.corner-mark::after {
  content: '';
  position: absolute;
  background: currentColor;
}
.corner-mark::before { left: 4px; top: 0; width: 1px; height: 9px; }
.corner-mark::after  { left: 0; top: 4px; width: 9px; height: 1px; }
.corner-mark.tl { left: 6px;  top: 6px; }
.corner-mark.tr { right: 6px; top: 6px; }
.corner-mark.bl { left: 6px;  bottom: 6px; }
.corner-mark.br { right: 6px; bottom: 6px; }
.card:hover .corner-mark { opacity: .8; color: var(--pink-soft); }

/* ---------------------------------------------- 文章结尾 END 带 */
.post-end {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-x1) 0 var(--sp-1);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .48em;
  color: rgba(255, 122, 184, .7);
}
.pe-line {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 45, 120, .45), transparent);
}
.pe-text { flex: none; text-shadow: 0 0 10px rgba(255, 45, 120, .5); }

/* ---------------------------------------------- 页脚警示条 */
.footer-warn {
  display: flex;
  justify-content: center;
  margin-bottom: var(--sp-4);
}
.footer-warn span {
  padding: var(--sp-1) var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .34em;
  color: rgba(255, 122, 184, .85);
  border: 1px dashed var(--line-pink);
  border-radius: 999px;
  background: rgba(255, 45, 120, .06);
}

/* ---------------------------------------------- 名字心意彩蛋 */
.profile .name {
  cursor: pointer;
  user-select: none;
  transition: text-shadow var(--dur-1) var(--ease-std), color var(--dur-1) var(--ease-std);
}
.profile .name:hover { color: #fff; text-shadow: var(--glow-pink); }
.profile .name.tapped { animation: name-tap var(--dur-3) var(--ease-std); }
@keyframes name-tap {
  0%, 100% { transform: scale(1); }
  35% { transform: scale(1.14); }
  60% { transform: scale(.97); }
}
.name-heart {
  position: fixed;
  z-index: 9997;
  font-size: var(--fs-base);
  color: var(--pink);
  pointer-events: none;
  text-shadow: 0 0 10px rgba(255, 45, 120, .9);
  animation: name-heart 1.5s var(--ease-out) forwards;
}
@keyframes name-heart {
  0%   { opacity: 1; transform: translate(0, 0) scale(.7) rotate(0deg); }
  100% { opacity: 0; transform: translate(var(--dx, 0), -86px) scale(1.25) rotate(var(--rot, 20deg)); }
}

/* ---------------------------------------------- 响应式 */
@media (max-width: 1200px) {
  .hud { display: none; }
}

@media (max-width: 720px) {
  .ribbon { height: 21px; }
  .ribbon-run { font-size: var(--fs-2xs); letter-spacing: .16em; }
  .curtain { font-size: var(--fs-2xs); letter-spacing: .3em; gap: var(--sp-h3); }
  .post-body h2.has-num { padding-left: var(--sp-8); }
  .post-body h2.has-num::before { width: 28px; font-size: var(--fs-xs); }
  .post-body h2.has-num::after { left: 33px; }
  .post-body img.jirai-photo { padding: var(--sp-h2); transform: none; }
  .post-body picture:nth-of-type(n) img.jirai-photo { transform: none; }
  .toast { bottom: 16px; font-size: var(--fs-sm); }
}

@media (prefers-reduced-motion: reduce) {
  .ribbon-track, .halo-layer i, .med-cursor svg, .heart-beat .ico { animation: none !important; }
  .halo-layer { display: none; }
}

/* ===== jirai-boom.css ===== */
/* ============================================================
   jirai-boom — 震撼层
   开机自检 / 全屏粒子画布 / 章节导航轨 / 氛围音（Web Audio）
   ============================================================ */

/* ---------------------------------------------- 开机自检 */
.boot {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #050308;
  font-family: var(--font-mono);
  overflow: hidden;
  transition: opacity .22s ease, visibility 0s .22s;
}
.boot::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(to bottom,
    rgba(255, 45, 120, .05) 0 1px, transparent 1px 3px);
  pointer-events: none;
}
.boot.mask-hide { opacity: 0; visibility: hidden; }

/* 网格背景 */
.boot-grid {
  position: absolute;
  inset: -20% -10%;
  background-image:
    linear-gradient(rgba(255, 45, 120, .12) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 45, 120, .12) 1px, transparent 1px);
  background-size: 46px 46px;
  transform: perspective(420px) rotateX(58deg);
  opacity: .5;
  animation: boot-grid-run 9s var(--ease-loop) infinite;
}
@keyframes boot-grid-run { to { background-position: 0 46px, 46px 0; } }

.boot-panel {
  position: relative;
  z-index: 4;
  width: min(92vw, 640px);
  padding: var(--sp-x1) var(--sp-x1) var(--sp-6);
  background: linear-gradient(180deg, rgba(20, 13, 23, .92), rgba(8, 5, 10, .92));
  border: 1px solid var(--line-pink);
  border-radius: 14px;
  box-shadow: 0 0 60px rgba(255, 45, 120, .22), inset 0 0 50px rgba(255, 45, 120, .05);
  transition: opacity var(--dur-3) var(--ease-std), transform var(--dur-3) var(--ease-std);
}
.boot.open .boot-panel { opacity: 0; transform: scale(1.05); }

.boot-brand {
  display: flex;
  align-items: baseline;
  gap: var(--sp-h3);
  flex-wrap: wrap;
}
.boot-mark {
  color: var(--pink);
  font-size: var(--fs-lg);
  line-height: 1;
  text-shadow: 0 0 12px rgba(255, 45, 120, .9);
  animation: heartbeat 2s var(--ease-std) infinite;
}
.boot-title {
  position: relative;
  font-family: var(--font-head);
  font-size: var(--fs-2xl);
  font-weight: 700;
  letter-spacing: .14em;
  color: #fff;
  text-shadow: 0 0 12px rgba(255, 45, 120, .6);
}
.boot-title::before,
.boot-title::after {
  content: attr(data-text);
  position: absolute;
  left: 0; top: 0;
  pointer-events: none;
}
.boot-title::before { color: var(--pink); animation: boot-glitch-a 2.4s steps(1) infinite; }
.boot-title::after  { color: var(--purple); animation: boot-glitch-b 3.1s steps(1) infinite; }
@keyframes boot-glitch-a {
  0%, 88%, 100% { transform: translate(0); opacity: 0; clip-path: inset(0 0 55% 0); }
  89% { transform: translate(-3px, -2px); opacity: .9; }
  92% { transform: translate(2px, 1px); opacity: .5; }
}
@keyframes boot-glitch-b {
  0%, 82%, 100% { transform: translate(0); opacity: 0; clip-path: inset(52% 0 0 0); }
  84% { transform: translate(3px, 2px); opacity: .85; }
  87% { transform: translate(-2px, 1px); opacity: .45; }
}
.boot-ver {
  margin-left: auto;
  font-size: var(--fs-xs);
  letter-spacing: .16em;
  color: var(--text-faint);
}
.boot-sub {
  margin: var(--sp-2) 0 var(--sp-5);
  padding-bottom: var(--sp-3-5);
  font-size: var(--fs-xs);
  letter-spacing: .16em;
  color: var(--text-dim);
  border-bottom: 1px dashed var(--line);
}

.boot-log {
  min-height: 132px;
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--pink-soft);
}
.boot-line {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transform: translateX(-8px);
}
.boot-line.show { animation: boot-line-in var(--dur-2) var(--ease-std) forwards; }
.boot-line::before { content: '› '; color: var(--pink); }
.boot-line.bad { color: var(--bad); }
.boot-line.bad::before { content: '✕ '; color: #ff3b3b; }
.boot-line.warn { color: #ffc26b; }
.boot-line.warn::before { content: '! '; color: var(--warn); }
@keyframes boot-line-in {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0); }
}

.boot-bar {
  position: relative;
  height: 4px;
  margin: var(--sp-5) 0 var(--sp-3);
  border-radius: 3px;
  background: rgba(255, 255, 255, .07);
  overflow: hidden;
}
.boot-bar i {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  background: linear-gradient(90deg, var(--pink), var(--purple));
  box-shadow: 0 0 14px rgba(255, 45, 120, .9);
}
.boot-bar::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .28), transparent);
  transform: translateX(-100%);
  animation: boot-sheen 1.1s var(--ease-loop) infinite;
}
@keyframes boot-sheen { to { transform: translateX(100%); } }

.boot-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-xs);
  color: var(--text-faint);
  letter-spacing: .14em;
}
.boot-pct b { color: var(--pink); font-size: var(--fs-sm); text-shadow: var(--glow-pink); }
.boot-skip {
  padding: 3px var(--sp-h4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .12em;
  color: var(--text-dim);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: all var(--dur-1) var(--ease-std);
}
.boot-skip:hover { color: #fff; border-color: var(--pink); box-shadow: var(--glow-soft); }

.boot-finish {
  margin: var(--sp-3-5) 0 0;
  font-size: var(--fs-sm);
  letter-spacing: .3em;
  text-align: center;
  color: var(--pink);
  opacity: 0;
  text-shadow: 0 0 16px rgba(255, 45, 120, .8);
}
.boot-finish.show { animation: boot-finish-in var(--dur-3) var(--ease-std) forwards; }
@keyframes boot-finish-in {
  from { opacity: 0; letter-spacing: .5em; transform: scale(.96); }
  to   { opacity: 1; letter-spacing: .3em; transform: scale(1); }
}

/* 幕布：先隐藏，开启动画时闪入并向两侧拉开 */
.boot-shutter {
  position: absolute;
  top: 0; bottom: 0;
  width: 50.5%;
  z-index: 3;
  opacity: 0;
  background: linear-gradient(90deg, #0a060d, #050308);
  transition: transform .85s var(--ease-curtain), opacity var(--dur-1) var(--ease-std);
}
.boot-shutter.left  { left: 0; }
.boot-shutter.right { right: 0; }
.boot-shutter.left::after,
.boot-shutter.right::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--pink), var(--purple), transparent);
  box-shadow: 0 0 22px rgba(255, 45, 120, .95);
}
.boot-shutter.left::after { right: 0; }
.boot-shutter.right::after { left: 0; }
.boot.open .boot-shutter { opacity: 1; }
.boot.open .boot-shutter.left  { transform: translateX(-100%); }
.boot.open .boot-shutter.right { transform: translateX(100%); }

/* 完成文字显示在幕布之上 */
.boot.open .boot-finish { z-index: 5; position: relative; }

/* 闪白 */
.boot.flash::before {
  background: #ff2d78;
  opacity: 0;
  animation: boot-flash var(--dur-3) var(--ease-out);
}
@keyframes boot-flash {
  0% { opacity: .5; }
  100% { opacity: 0; }
}

/* 无脚本 / 已播过：直接隐藏 */
.no-js .boot,
.boot.mask-hide,
html.boot-skip .boot { display: none !important; }

/* ---------------------------------------------- 粒子画布 */
.particles {
  position: fixed;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ---------------------------------------------- 章节导航轨 */
/* 有章节导航轨时，隐藏滚动 HUD，避免右侧信息打架 */
body.has-rail .hud { display: none; }

.rail {
  position: fixed;
  right: 68px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 899;
  max-width: 200px;
  pointer-events: auto;
}
.rail-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-h3);
  align-items: flex-end;
}
.rail-item { position: relative; display: flex; align-items: center; gap: var(--sp-2); }
.rail-item .rail-txt {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: var(--fs-xs);
  letter-spacing: .04em;
  color: var(--text-faint);
  opacity: 0;
  transition: max-width var(--dur-2) var(--ease-std), opacity var(--dur-2) var(--ease-std), color var(--dur-1) var(--ease-std);
}
.rail-item a {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  text-decoration: none;
}
.rail-item .rail-dot {
  flex: none;
  width: 8px; height: 8px;
  border: 1px solid var(--line-pink);
  border-radius: 50%;
  background: rgba(255, 45, 120, .16);
  transition: all var(--dur-2) var(--ease-std);
}
.rail-item:hover .rail-txt,
.rail-item.active .rail-txt { max-width: 168px; opacity: 1; }
.rail-item:hover .rail-txt { color: #fff; }
.rail-item.active .rail-dot {
  width: 11px; height: 11px;
  background: var(--pink);
  border-color: var(--pink);
  box-shadow: 0 0 12px rgba(255, 45, 120, .95);
}
.rail-item.active .rail-txt { color: var(--pink-soft); }
.rail-item.lvl-3 .rail-dot { width: 6px; height: 6px; }
.rail-item.lvl-3 .rail-txt { font-size: var(--fs-xs); }
.rail-item.lvl-4 { display: none; }
.rail::before {
  content: '';
  position: absolute;
  right: 3.5px; top: 6px; bottom: 6px;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--line-pink), transparent);
  z-index: -1;
}

/* ---------------------------------------------- 氛围音开关 */
.ambient {
  position: fixed;
  left: 18px;
  bottom: 22px;
  z-index: 950;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-h5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .16em;
  color: var(--text-dim);
  background: rgba(14, 8, 17, .88);
  border: 1px solid var(--line);
  border-radius: 999px;
  backdrop-filter: blur(8px);
  cursor: pointer;
  transition: all var(--dur-2) var(--ease-std);
}
.ambient:hover { color: #fff; border-color: var(--line-pink); box-shadow: 0 0 18px rgba(255, 45, 120, .22); }
.ambient[aria-pressed="true"] {
  color: #fff;
  border-color: var(--pink);
  box-shadow: 0 0 22px rgba(255, 45, 120, .4), inset 0 0 14px rgba(255, 45, 120, .14);
}
.amb-bars { display: flex; align-items: flex-end; gap: var(--sp-0-5); height: 12px; }
.amb-bars i {
  width: 2px;
  height: 4px;
  background: currentColor;
  border-radius: 1px;
  transition: height var(--dur-1) var(--ease-std);
}
.ambient[aria-pressed="true"] .amb-bars i { animation: amb-eq var(--dur-3) var(--ease-std) infinite; background: var(--pink); }
.ambient[aria-pressed="true"] .amb-bars i:nth-child(2) { animation-delay: .15s; }
.ambient[aria-pressed="true"] .amb-bars i:nth-child(3) { animation-delay: .3s; }
.ambient[aria-pressed="true"] .amb-bars i:nth-child(4) { animation-delay: .45s; }
@keyframes amb-eq {
  0%, 100% { height: 4px; }
  50% { height: 12px; }
}

/* ---------------------------------------------- 胶片颗粒 */
.grain {
  position: fixed;
  inset: var(--offset-deco-md);
  z-index: 9995;
  pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain-move .6s steps(3) infinite;
}
@keyframes grain-move {
  0%   { transform: translate(0, 0); }
  33%  { transform: translate(-24px, 16px); }
  66%  { transform: translate(18px, -20px); }
  100% { transform: translate(0, 0); }
}

/* ---------------------------------------------- 踩雷爆点 */
.lm-message {
  position: fixed;
  left: 50%;
  top: 42%;
  z-index: 9994;
  transform: translate(-50%, -50%) scale(.7);
  padding: var(--sp-3-5) var(--sp-x1);
  font-family: var(--font-head);
  font-size: clamp(22px, 5vw, 46px);
  font-weight: 700;
  letter-spacing: .14em;
  color: #fff;
  white-space: nowrap;
  background: rgba(8, 5, 10, .82);
  border: 2px solid var(--pink);
  border-radius: 6px;
  box-shadow: 0 0 60px rgba(255, 45, 120, .6), inset 0 0 40px rgba(255, 45, 120, .18);
  text-shadow: 0 0 18px rgba(255, 45, 120, 1), 0 0 42px rgba(168, 85, 247, .7);
  pointer-events: none;
  opacity: 0;
  /* 注意：不要拆成两个同时作用于 opacity 的动画——
     多个动画叠加时会相乘，导致整体永远透明。用一个时间轴搞定。 */
  animation: lm-show 3.1s var(--ease-out) forwards;
}
@keyframes lm-show {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.62) rotate(-2.5deg); }
  7%   { opacity: 1; transform: translate(-50%, -50%) scale(1.07) rotate(.8deg); }
  11%  { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
  14%  { opacity: 1; transform: translate(-53%, -50%) scale(1) skewX(6deg); }
  17%  { opacity: 1; transform: translate(-47%, -50%) scale(1) skewX(-6deg); }
  20%  { opacity: 1; transform: translate(-50%, -50%) scale(1) skewX(0); }
  78%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.16); }
}

.lm-blast {
  position: fixed;
  z-index: 9993;
  width: 14px; height: 14px;
  border-radius: 50%;
  pointer-events: none;
  background: var(--pink);
  box-shadow: 0 0 24px 6px rgba(255, 45, 120, .9);
  animation: lm-blast var(--dur-3) var(--ease-out) forwards;
}
@keyframes lm-blast {
  from { opacity: .95; transform: scale(.2); }
  to   { opacity: 0; transform: scale(34); }
}

/* 文字故障（生成器图案） */
.boot-title.glitch-once,
.glitch-once {
  animation: glitch-shake var(--dur-3) steps(2) 2;
}
@keyframes glitch-shake {
  0%, 100% { transform: translate(0); filter: none; }
  20% { transform: translate(-4px, 2px); filter: hue-rotate(60deg) saturate(2); }
  40% { transform: translate(4px, -2px); }
  60% { transform: translate(-2px, -1px); filter: hue-rotate(-50deg); }
  80% { transform: translate(3px, 1px); }
}

/* ---------------------------------------------- 危险区抖动 */
/* 注意：抖动必须作用在 .wrap 上，不能作用在 body 上——
   body 一旦有 transform 就会成为 position:fixed 的包含块，
   弹幕/光标/画布全都会被按文档高度重新定位而飞出屏幕。 */
.wrap.shake { animation: danger-shake var(--dur-3) var(--ease-shake); }
@keyframes danger-shake {
  10%, 90% { transform: translate(-2px, 1px) rotate(-.4deg); }
  20%, 80% { transform: translate(3px, -2px) rotate(.5deg); }
  30%, 50%, 70% { transform: translate(-4px, 2px) rotate(-.6deg); }
  40%, 60% { transform: translate(4px, -1px) rotate(.6deg); }
}

/* 危险警告闪层 */
.danger-veil {
  position: fixed;
  inset: 0;
  z-index: 9990;
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(circle at 50% 50%, transparent 35%, rgba(255, 45, 120, .28) 100%),
    repeating-linear-gradient(45deg, rgba(255, 45, 120, .12) 0 24px, transparent 24px 48px);
}
.danger-veil.on { animation: danger-veil var(--dur-3) var(--ease-out); }
@keyframes danger-veil {
  0% { opacity: 1; }
  100% { opacity: 0; }
}

/* ---------------------------------------------- 响应式 */
@media (max-width: 1280px) {
  .rail { display: none; }
}
@media (max-width: 720px) {
  .boot-panel { padding: var(--sp-5-5) var(--sp-4-5) var(--sp-4-5); width: min(94vw, 520px); }
  .boot-title { font-size: var(--fs-xl); }
  .boot-ver { display: none; }
  .boot-log { font-size: var(--fs-xs); min-height: 112px; }
  .ambient { left: 12px; bottom: 14px; padding: var(--sp-h2) var(--sp-2-5); }
  .amb-label { display: none; }
  .grain { opacity: .04; }
}

@media (prefers-reduced-motion: reduce) {
  .boot, .boot-shutter, .boot-grid, .boot-title::before, .boot-title::after,
  .grain, .amb-bars i, .boot-mark { animation: none !important; transition-duration: .01ms !important; }
  .boot { display: none !important; }
  .danger-veil { display: none; }
}

/* ===== jirai-niche.css ===== */
/* ============================================================
   jirai-niche — 檔案館化
   碎片檔案庫列表 / 卷宗印章 / 直排標題 / 頁邊批註 /
   未完句 / 複寫紙質感 / 繁體切換 / 低對比留白
   ============================================================ */

/* ---------------------------------------------- 全局：低對比與留白 */
body {
  --paper: #0b070d;
  --ink: #b9adc2;         /* 正文墨色（刻意壓低對比） */
  --ink-dim: #7d7189;
  --seal: #c0392b;        /* 朱印 */
  --seal-soft: rgba(192, 57, 43, .55);
}

/* 複寫紙底紋：極淡的橫線 + 噪點，讓整頁像掃描件 */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9992;
  pointer-events: none;
  opacity: .16;
  background-image:
    repeating-linear-gradient(0deg, rgba(185, 173, 194, .028) 0 1px, transparent 1px 4px),
    radial-gradient(ellipse at 50% 0%, rgba(192, 57, 43, .05), transparent 62%);
  mix-blend-mode: screen;
}
body.no-paper::after { display: none; }

/* 正文墨色壓低、行距收緊 */
.post-body {
  color: #c8bdd0;
  line-height: var(--lh-body);
}
.post-body strong { color: #ded4e4; text-shadow: none; }
.post-body h1, .post-body h2, .post-body h3, .post-body h4 { color: var(--text-head); }

/* ---------------------------------------------- 檔案目錄（首頁） */
.cabinet-head {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-3-5);
  flex-wrap: wrap;
  margin: var(--sp-0-5) 0 0;
  padding-bottom: var(--sp-5);
}
.cabinet-head .ch-title {
  margin: 0;
  font-family: var(--font-head);
  font-size: clamp(20px, 3vw, 27px);
  letter-spacing: .18em;
  color: var(--text-head);
}
.cabinet-head .ch-title span { color: var(--seal); }
.cabinet-head .ch-meta {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .18em;
  color: var(--ink-dim);
  text-align: right;
  line-height: var(--lh-body);
}

.cabinet {
  border-top: 1px solid var(--line);
}
.cab-row {
  display: grid;
  grid-template-columns: 96px 88px 1fr auto;
  align-items: baseline;
  gap: var(--sp-3-5);
  padding: var(--sp-4) var(--sp-1-5) var(--sp-4) var(--sp-0-5);
  border-bottom: 1px solid rgba(46, 32, 51, .85);
  text-decoration: none;
  position: relative;
  transition: background-color .18s ease, box-shadow .18s ease;
}
.cab-row::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--seal);
  opacity: 0;
  transition: opacity var(--dur-1) var(--ease-std);
}
.cab-row:hover, .cab-row:focus-visible {
  background-color: rgba(255, 122, 184, .035);
  box-shadow: inset 0 1px rgba(255, 122, 184, .035);
}
.cab-row:hover::before, .cab-row:focus-visible::before { opacity: 1; }

.cab-no {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  letter-spacing: .1em;
  color: var(--seal);
  opacity: .85;
  white-space: nowrap;
}
.cab-date {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .06em;
  color: var(--ink-dim);
  white-space: nowrap;
}
.cab-title {
  font-family: var(--font-head);
  font-size: var(--fs-md);
  letter-spacing: .04em;
  color: #ddd3e3;
  line-height: var(--lh-tight);
  transition: color .18s ease;
}
.cab-row:hover .cab-title, .cab-row:focus-visible .cab-title { color: #fff; }
.cab-type {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .12em;
  color: var(--ink-dim);
  white-space: nowrap;
  padding: var(--sp-0-5) var(--sp-h2);
  border: 1px solid rgba(46, 32, 51, .9);
  border-radius: 2px;
}
.cab-row:hover .cab-type { color: var(--seal); border-color: var(--seal-soft); }

.cabinet-foot {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-top: var(--sp-4-5);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .16em;
  color: var(--ink-dim);
}

/* 空櫃 */
.cabinet-empty {
  padding: var(--sp-x5) var(--sp-2-5);
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .2em;
  color: var(--ink-dim);
  border-bottom: 1px solid var(--line);
}

/* ---------------------------------------------- 卷宗頭（文章頁）
   結構：flex 兩欄 —— 直排書脊 | 卷宗內容。
   舊寫法用絕對定位 + min-height:96px 硬湊，書脊高度與標題高度各自為政，
   直排檔號會侵到下面的元資料列。改成 flex 後書脊自動撐滿 header 高度。 */
.dossier {
  border-bottom: 1px dashed rgba(46, 32, 51, .9);
  margin-bottom: var(--sp-6);
  padding-bottom: var(--sp-4);
}
/* 上排：書脊 + 標題（+ 絕對定位的朱印） */
.dossier-top {
  display: flex;
  align-items: stretch;
  gap: var(--sp-5);
}
/* 下排：元資料獨占整行，不再與朱印搶右側空間 */
.dossier .meta-row {
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid rgba(46, 32, 51, .7);
  padding-right: 0;
}
.dossier-spine {
  flex: none;
  width: 30px;
  padding-top: var(--sp-1);
  writing-mode: vertical-rl;
  text-orientation: upright;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  position: relative;
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  /* 只放档号（6 字符），高度约 76px，略高于单行标题 —— 相称。
     直排下 letter-spacing 会直接转成纵向长度，故设为 0，
     并降透明度让它退到背景层：书脊是装订标记，不是内容。 */
  letter-spacing: 0;
  color: var(--seal);
  opacity: .5;
}
.dossier-body {
  flex: 1;
  min-width: 0;      /* 让长标题能正常换行而不是撑破网格 */
  position: relative; /* 朱印以此为定位基准 */
}
/* 书脊底部的渐隐竖线：占满剩余高度，像档案夹的装订线 */
.dossier-spine::after {
  content: '';
  position: absolute;
  left: 50%; bottom: 0;
  width: 1px;
  height: 30px;
  background: linear-gradient(180deg, var(--seal-soft), transparent);
}
.dossier-spine .sp-no { font-size: var(--fs-xs); letter-spacing: 0; opacity: 1; }

/* 朱印固定在 header 右上角，标题让出这一带（已用 Range 行盒验证无重叠）。 */
.dossier-body h1 {
  /* 86px 不是版面节奏，而是「68px 印章 + 旋转外溢 ~10px + 呼吸 8px」推导出的
     避让尺寸，属组件内部几何，故保持字面值而非间距 token。 */
  padding-right: 86px;
}

.dossier h1 {
  margin: 0 0 var(--sp-2-5);
  font-family: var(--font-head);
  font-size: clamp(21px, 3.2vw, 29px);
  line-height: var(--lh-tight);
  letter-spacing: .05em;
  color: #eae1ef;
  text-shadow: none;
}
.dossier h1::after {
  content: '▌';
  margin-left: var(--sp-1);
  color: var(--seal);
  opacity: .45;
  font-size: .8em;
}
@keyframes caret-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* 朱印 */
.seal-mark {
  position: absolute;
  right: 2px;
  top: 4px;
  width: 68px;
  height: 68px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--seal);
  border-radius: 3px;
  transform: rotate(-7deg);
  color: var(--seal);
  opacity: .72;
  font-family: var(--font-head);
  font-size: var(--fs-xs);
  line-height: var(--lh-tight);
  letter-spacing: .1em;
  text-align: center;
  padding: var(--sp-h1);
  box-shadow: inset 0 0 0 3px rgba(192, 57, 43, .12);
  pointer-events: none;
}
.seal-mark::after {
  content: '';
  position: absolute;
  inset: -3px;
  border: 1px solid var(--seal-soft);
  border-radius: 4px;
  transform: rotate(2deg);
}

/* ---------------------------------------------- 卷宗內的元資料 */
.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1-5) var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .1em;
  color: var(--ink-dim);
}
.meta-row .k { color: var(--seal); opacity: .8; }
.meta-row a { color: var(--ink); border-bottom: 1px dotted var(--line-pink); }
.meta-row a:hover { color: #fff; text-shadow: none; }

/* ---------------------------------------------- 頁邊批註 */
.memo {
  position: relative;
  display: block;
  margin: var(--sp-5-5) 0;
  padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-x1);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: #9c8fa8;
  background: linear-gradient(90deg, rgba(192, 57, 43, .06), transparent 70%);
  border-left: 2px solid var(--seal-soft);
  border-radius: 0 4px 4px 0;
  font-style: normal;
}
.memo-pin {
  position: absolute;
  left: 8px; top: 10px;
  color: var(--seal);
  font-size: var(--fs-xs);
  opacity: .8;
}
.memo-body p { margin: 0 0 var(--sp-2); }
.memo-body p:last-child { margin-bottom: 0; }

/* 寬螢幕時浮到正文右側留白，像頁邊手寫 */
@media (min-width: 1400px) {
  .post-body { position: relative; }
  .memo {
    width: 190px;
    margin: var(--sp-1-5) var(--offset-deco-lg) var(--sp-5) 0;
    float: right;
    clear: right;
    padding: var(--sp-2-5) var(--sp-3) var(--sp-2-5) var(--sp-6-5);
    font-size: var(--fs-xs);
    line-height: var(--lh-snug);
    background: none;
    border-left: 1px solid var(--seal-soft);
    transform: rotate(-.6deg);
  }
  .memo::after {
    content: '';
    position: absolute;
    left: -1px; bottom: -34px;
    width: 1px; height: 30px;
    background: linear-gradient(180deg, var(--seal-soft), transparent);
  }
}

/* ---------------------------------------------- 未完句 */
.unfinished {
  position: relative;
  margin: var(--sp-6-5) 0;
  padding-left: var(--sp-4-5);
}
.uf-line {
  position: absolute;
  left: 0; top: 6px;
  width: 8px; height: 8px;
  background: var(--seal);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  opacity: .7;
}
.uf-body {
  color: #8d8199;
  font-size: var(--fs-base);
  line-height: var(--lh-body);
}
.uf-body::after {
  content: '';
  display: inline-block;
  width: 42px;
  margin-left: 3px;
  border-bottom: 1px dashed rgba(185, 173, 194, .45);
  vertical-align: middle;
}
.uf-mark {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .28em;
  color: var(--seal);
  opacity: .7;
}

/* ---------------------------------------------- 民國／西元紀年標記 */
.era {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .16em;
  color: var(--ink-dim);
}

/* ---------------------------------------------- 繁體切換鈕 */
.variant-btn {
  position: fixed;
  right: 18px;
  bottom: 22px;
  z-index: 951;
  display: flex;
  align-items: center;
  gap: var(--sp-h2);
  padding: var(--sp-h2) var(--sp-h4);
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  letter-spacing: .1em;
  color: var(--seal);
  background: rgba(11, 7, 13, .88);
  border: 1px solid var(--seal-soft);
  border-radius: 3px;
  cursor: pointer;
  backdrop-filter: blur(8px);
  transition: all var(--dur-1) var(--ease-std);
}
.variant-btn:hover { color: #fff; border-color: var(--seal); box-shadow: 0 0 16px rgba(192, 57, 43, .35); }
.variant-btn small {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .14em;
  color: var(--ink-dim);
}
.variant-btn[aria-pressed="true"] { color: #fff; border-color: var(--seal); background: rgba(192, 57, 43, .18); }

/* 進行轉換的瞬間閃一下，像換裝 */
.variant-flash { animation: variant-flash var(--dur-3) var(--ease-std); }
@keyframes variant-flash {
  0% { filter: contrast(1.5) brightness(1.25) saturate(.4); }
  100% { filter: none; }
}

/* ---------------------------------------------- 版面分配
   实测（1920 视口）：内容块占 65%，左右边距各 340px，完全对称（asymmetry 0）。
   旧写法把主栏锁死在 820px，而列表页放宽到 960px，宽屏下两者不连贯。
   改为流式：正文页与列表页各有一条平滑曲线，列表页宽一档（表格化内容更需横向空间）。 */
@media (min-width: 1100px) {
  .layout { grid-template-columns: minmax(0, 1fr) 280px; gap: var(--sp-7); }
  .main-col { max-width: clamp(780px, 58vw, 900px); }
  .cabinet .cab-row { grid-template-columns: 88px 80px 1fr auto; }
}

/* 列表页（档案库 / 病历库）不放侧栏：一行一条本来就不需要 */
@media (min-width: 1100px) {
  .layout.no-side { max-width: clamp(860px, 64vw, 1020px); }
}

/* 超宽屏：编号列与日期列再放宽，避免与标题挤在一起 */
@media (min-width: 1500px) {
  .cabinet .cab-row { grid-template-columns: 96px 92px 1fr auto; gap: var(--sp-5); }
}

/* ---------------------------------------------- 響應式 */
@media (max-width: 720px) {
  .cabinet-head { flex-direction: column; align-items: flex-start; gap: 8px; padding-bottom: 18px; }
  .cabinet-head .ch-meta { margin-left: 0; text-align: left; letter-spacing: .08em; }
  .cab-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "no date type"
      "ttl ttl ttl";
    gap: 8px 10px;
    padding: 16px 4px;
  }
  .cab-no { grid-area: no; font-size: 11px; letter-spacing: .06em; }
  .cab-type { grid-area: type; justify-self: end; padding: 2px 6px; font-size: 10px; letter-spacing: .04em; }
  .cab-title { grid-area: ttl; min-width: 0; font-size: var(--fs-base); line-height: 1.65; letter-spacing: .035em; overflow-wrap: anywhere; }
  .cab-date { grid-area: date; font-size: 10px; letter-spacing: .02em; }

  .dossier { padding-left: 0; padding-top: var(--sp-1); }
  .dossier-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "spine seal" "title title"; gap: 14px 12px; align-items: center; }
  .dossier-body { display: contents; }
  .dossier-body h1 { grid-area: title; min-width: 0; margin: 0; padding-right: 0; font-size: clamp(22px, 5.4vw, 28px); line-height: 1.5; letter-spacing: .035em; text-wrap: balance; }
  .dossier .meta-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 9px 12px; margin-top: 20px; padding-top: 16px; font-size: 11px; letter-spacing: .035em; }
  .post-meta-reading, .post-meta-updated { grid-column: 1 / -1; }
  .dossier-spine {
    grid-area: spine;
    position: static;
    writing-mode: horizontal-tb;
    flex-direction: row;
    width: auto;
    margin-bottom: 0;
    gap: var(--sp-3);
  }
  .dossier-spine::after { display: none; }
  .dossier .seal-mark {
    grid-area: seal;
    position: static;
    width: auto; min-width: 44px; height: 28px;
    flex-direction: row;
    gap: 6px;
    padding: 4px 8px;
    line-height: 1;
    margin: 0 2px 0 0;
    font-size: 10px;
    transform: rotate(-3deg);
  }
  .variant-btn { right: 12px; bottom: 66px; padding: var(--sp-1-5) var(--sp-h3); font-size: var(--fs-xs); }
  .variant-btn small { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .dossier h1::after { animation: none; }
  .variant-flash { animation: none; }
}

/* ===== jirai-niche-extra.css ===== */
/* ============================================================
   jirai-niche-extra — 檔案館質感補強
   直角化 / 尋檔懸停 / 最新入庫戳記 / 條碼頁腳
   ============================================================ */

/* ---------------------------------------------- 直角化：去掉圓潤感 */
.nav-links a { border-radius: 3px; }
.nav-links a.active::after { bottom: -5px; }
.pager a, .pager span { border-radius: 3px; }
.tag-chip { border-radius: 2px; }
.tag-cloud a { border-radius: 2px; }
.profile .avatar, .profile .avatar-fallback { border-radius: 4px; }
.widget { border-radius: 4px; }
.card { border-radius: 4px; }
.toc-box { border-radius: 3px; }
.term { border-radius: 3px; }
.term::after { border-radius: 2px; }
.post-nav a { border-radius: 3px; }
.cab-type { border-radius: 2px; }
.to-top, .ambient { border-radius: 4px; }
.variant-btn { border-radius: 2px; }
.room-tag { border-radius: 2px; }
.barcode { opacity: .5; }

/* ---------------------------------------------- 尋檔懸停 */
.cab-row { cursor: crosshair; }
.cab-row:hover .cab-no { color: #f0b3c9; text-shadow: 0 0 7px rgba(255, 45, 120, .3); }
.cab-row:hover .cab-type {
  color: var(--seal);
  border-color: var(--seal-soft);
}
.cab-no, .cab-type { transition: color .18s ease, border-color .18s ease, text-shadow .18s ease; }

/* ---------------------------------------------- 卷宗內的細節 */
.dossier h1 { word-break: break-word; }
.meta-row .k::after { content: '：'; opacity: .5; }

/* 診斷碼標籤改成病歷貼紙感 */
.post-foot .tag-chip {
  font-family: var(--font-mono);
  letter-spacing: .08em;
  background-image: repeating-linear-gradient(
    45deg,
    rgba(192, 57, 43, .16) 0 4px,
    rgba(192, 57, 43, 0) 4px 8px
  );
  border-color: rgba(192, 57, 43, .4);
  color: #d3a49c;
}
.post-foot .tag-chip:hover {
  background: rgba(192, 57, 43, .22);
  border-color: var(--seal);
  color: #fff;
  box-shadow: 0 0 14px rgba(192, 57, 43, .4);
}

/* 引用的 [!memo] 在窄螢幕下不浮動 */
@media (max-width: 1399px) {
  .memo { float: none; width: auto; }
}

/* ---------------------------------------------- 首頁卷宗標題的紅點 */
.ch-title span { text-shadow: 0 0 12px rgba(192, 57, 43, .8); }

/* 乾掉的血跡：標題底部一點暈染 */
.cabinet-head { position: relative; }
.cabinet-head::after {
  content: '';
  position: absolute;
  left: 0; bottom: -1px;
  width: 74px; height: 3px;
  background: linear-gradient(90deg, var(--seal), transparent);
  opacity: .55;
  filter: blur(1px);
}

@media (max-width: 720px) {
  .cab-row.is-new::after { display: none; }
  .dossier { min-height: 0; padding-left: 0; }
  .dossier-spine { height: auto; width: auto; }
}

/* 留念入口：同一套档案排版，仅用淡紫题签识别。 */
.cab-row.is-memorial .cab-type { color: #c7bbd1; border-color: #55445f; }
@media (max-width: 980px) { .side .profile:last-child { grid-column: 1 / -1; } }

/* ===== jirai-texture.css ===== */
/* ============================================================
   jirai-texture — 質感層
   蕾絲畫框 / 直排側帶 / 心電監護條 / 複寫紙網紋 / 繃帶分隔 / 墨滲
   ============================================================ */

/* ---------------------------------------------- 全屏蕾絲畫框 */
.laceframe {
  position: fixed;
  inset: 0;
  z-index: 9991;
  pointer-events: none;
}
/* 四邊蕾絲條 */
.laceframe i {
  position: absolute;
  background-repeat: repeat;
  opacity: .5;
}
.laceframe .lf-top,
.laceframe .lf-bottom {
  left: 0; right: 0;
  height: 13px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='13'%3E%3Cpath d='M0 0h28v1.6c-2.3 0-4.2 2-4.2 4.5s1.9 4.5 4.2 4.5V13H0v-2.4c2.3 0 4.2-2 4.2-4.5S2.3 1.6 0 1.6z' fill='%23ff2d78' fill-opacity='0.20'/%3E%3Ccircle cx='14' cy='6.1' r='1.1' fill='%23ff2d78' fill-opacity='0.42'/%3E%3C/svg%3E");
  background-size: 28px 13px;
}
.laceframe .lf-top { top: 0; }
.laceframe .lf-bottom { bottom: 0; transform: scaleY(-1); }
.laceframe .lf-left,
.laceframe .lf-right {
  top: 0; bottom: 0;
  width: 13px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='28'%3E%3Cpath d='M0 0v28h1.6c0-2.3 2-4.2 4.5-4.2s4.5 1.9 4.5 4.2H13V0h-2.4c0 2.3-2 4.2-4.5 4.2S1.6 2.3 1.6 0z' fill='%23ff2d78' fill-opacity='0.20'/%3E%3Ccircle cx='6.1' cy='14' r='1.1' fill='%23ff2d78' fill-opacity='0.42'/%3E%3C/svg%3E");
  background-size: 13px 28px;
}
.laceframe .lf-left { left: 0; }
.laceframe .lf-right { right: 0; transform: scaleX(-1); }

/* 四角花飾 */
.laceframe b {
  position: absolute;
  width: 74px; height: 74px;
  background-repeat: no-repeat;
  background-size: contain;
  opacity: .72;
  filter: drop-shadow(0 0 6px rgba(255, 45, 120, .35));
}
.laceframe b::after {
  content: '';
  position: absolute;
  width: 9px; height: 9px;
  background: var(--pink);
  box-shadow: 0 0 8px rgba(255, 45, 120, .9);
  transform: rotate(45deg);
}
.laceframe .lf-tl { top: 8px; left: 8px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='74' height='74' viewBox='0 0 74 74'%3E%3Cg fill='none' stroke='%23ff2d78' stroke-opacity='0.55' stroke-width='1.2'%3E%3Cpath d='M2 42a40 40 0 0 1 40-40M2 60A58 58 0 0 1 60 2M2 72A70 70 0 0 1 72 2'/%3E%3Cpath d='M8 30c6 0 10-4 10-10 0 6 4 10 10 10-6 0-10 4-10 10 0-6-4-10-10-10z' fill='%23ff2d78' fill-opacity='0.3' stroke='none'/%3E%3C/g%3E%3C/svg%3E");
}
.laceframe .lf-tl::after { top: 0; left: 0; }
.laceframe .lf-tr { top: 8px; right: 8px; transform: scaleX(-1);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='74' height='74' viewBox='0 0 74 74'%3E%3Cg fill='none' stroke='%23ff2d78' stroke-opacity='0.55' stroke-width='1.2'%3E%3Cpath d='M2 42a40 40 0 0 1 40-40M2 60A58 58 0 0 1 60 2M2 72A70 70 0 0 1 72 2'/%3E%3Cpath d='M8 30c6 0 10-4 10-10 0 6 4 10 10 10-6 0-10 4-10 10 0-6-4-10-10-10z' fill='%23ff2d78' fill-opacity='0.3' stroke='none'/%3E%3C/g%3E%3C/svg%3E");
}
.laceframe .lf-tr::after { top: 0; right: 0; }
.laceframe .lf-bl { bottom: 8px; left: 8px; transform: scaleY(-1);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='74' height='74' viewBox='0 0 74 74'%3E%3Cg fill='none' stroke='%23ff2d78' stroke-opacity='0.55' stroke-width='1.2'%3E%3Cpath d='M2 42a40 40 0 0 1 40-40M2 60A58 58 0 0 1 60 2M2 72A70 70 0 0 1 72 2'/%3E%3Cpath d='M8 30c6 0 10-4 10-10 0 6 4 10 10 10-6 0-10 4-10 10 0-6-4-10-10-10z' fill='%23ff2d78' fill-opacity='0.3' stroke='none'/%3E%3C/g%3E%3C/svg%3E");
}
.laceframe .lf-bl::after { bottom: 0; left: 0; }
.laceframe .lf-br { bottom: 8px; right: 8px; transform: scale(-1, -1);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='74' height='74' viewBox='0 0 74 74'%3E%3Cg fill='none' stroke='%23ff2d78' stroke-opacity='0.55' stroke-width='1.2'%3E%3Cpath d='M2 42a40 40 0 0 1 40-40M2 60A58 58 0 0 1 60 2M2 72A70 70 0 0 1 72 2'/%3E%3Cpath d='M8 30c6 0 10-4 10-10 0 6 4 10 10 10-6 0-10 4-10 10 0-6-4-10-10-10z' fill='%23ff2d78' fill-opacity='0.3' stroke='none'/%3E%3C/g%3E%3C/svg%3E");
}
.laceframe .lf-br::after { bottom: 0; right: 0; }

body.no-laceframe .laceframe { display: none; }

/* ---------------------------------------------- 直排側帶 */
.sidetab {
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 898;
  display: flex;
  align-items: center;
  gap: var(--sp-2-5);
  padding: var(--sp-4) var(--sp-h1) var(--sp-4) 3px;
  writing-mode: vertical-rl;
  text-orientation: upright;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .18em;
  color: rgba(255, 122, 184, .6);
  background: linear-gradient(180deg, transparent, rgba(10, 6, 13, .85) 18%, rgba(10, 6, 13, .85) 82%, transparent);
  border-right: 1px solid rgba(255, 45, 120, .18);
  pointer-events: none;
  user-select: none;
}
.sidetab::before {
  content: '✚';
  color: var(--pink);
  font-size: var(--fs-xs);
  writing-mode: horizontal-tb;
  text-shadow: 0 0 10px rgba(255, 45, 120, .8);
  animation: heartbeat 2.6s var(--ease-std) infinite;
}
.sidetab::after {
  content: '';
  width: 1px;
  height: 46px;
  background: linear-gradient(180deg, var(--pink), transparent);
  writing-mode: horizontal-tb;
}

/* ---------------------------------------------- 心電監護條 */
.ecg-strip {
  position: relative;
  margin: var(--sp-x2) 0;
  height: 56px;
  overflow: hidden;
  border-top: 1px solid rgba(255, 45, 120, .16);
  border-bottom: 1px solid rgba(255, 45, 120, .16);
  background:
    linear-gradient(180deg, rgba(255, 45, 120, .04), transparent 60%),
    repeating-linear-gradient(90deg, rgba(255, 45, 120, .09) 0 1px, transparent 1px 34px);
}
.ecg-strip svg {
  position: absolute;
  left: 0; top: 14px;
  width: 200%;
  height: 100%;
  animation: ecg-run 7s var(--ease-loop) infinite;
}
.ecg-strip svg path {
  fill: none;
  stroke: var(--pink);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 5px rgba(255, 45, 120, .85));
}
.ecg-strip .ecg-lead {
  position: absolute;
  right: 8px; bottom: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .22em;
  color: rgba(255, 122, 184, .5);
}
.ecg-strip .ecg-bpm {
  position: absolute;
  left: 8px; bottom: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .18em;
  color: var(--pink);
  opacity: .8;
  text-shadow: 0 0 8px rgba(255, 45, 120, .7);
}
@keyframes ecg-run {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ---------------------------------------------- 複寫紙網紋 */
body.crosshatch .card,
body.crosshatch .widget,
body.crosshatch .term {
  background-image:
    repeating-linear-gradient(45deg, rgba(255, 45, 120, .028) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(-45deg, rgba(255, 45, 120, .022) 0 1px, transparent 1px 9px),
    linear-gradient(180deg, var(--bg-card), var(--bg-soft));
}
body.crosshatch .cabinet {
  background-image: repeating-linear-gradient(0deg, rgba(255, 45, 120, .022) 0 1px, transparent 1px 6px);
}
/* 檔案列加一格一格的格線感 */
body.crosshatch .cab-row:nth-child(odd) {
  background-image: linear-gradient(90deg, rgba(255, 45, 120, .022), transparent 40%);
}

/* ---------------------------------------------- 繃帶分隔（<hr>） */
body.bandage-hr .post-body hr {
  height: 26px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='88' height='26' viewBox='0 0 88 26'%3E%3Cg%3E%3Crect x='0' y='8' width='88' height='10' rx='5' fill='%23ff2d78' fill-opacity='0.07'/%3E%3Cg fill='%23ff2d78' fill-opacity='0.34'%3E%3Crect x='6' y='10' width='4' height='6' rx='1'/%3E%3Crect x='15' y='10' width='4' height='6' rx='1'/%3E%3Crect x='24' y='10' width='4' height='6' rx='1'/%3E%3Crect x='60' y='10' width='4' height='6' rx='1'/%3E%3Crect x='69' y='10' width='4' height='6' rx='1'/%3E%3Crect x='78' y='10' width='4' height='6' rx='1'/%3E%3C/g%3E%3Cg stroke='%23ff2d78' stroke-opacity='0.5' stroke-width='1.1' fill='none'%3E%3Ccircle cx='44' cy='13' r='6'/%3E%3Cpath d='M44 7v12M38 13h12'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  background-repeat: repeat-x;
  background-position: center;
  background-size: auto 26px;
}

/* ---------------------------------------------- 標題墨滲 */
.ink {
  position: relative;
  display: inline-block;
}
.ink::after {
  content: '';
  position: absolute;
  left: -4px; right: -4px; bottom: -.12em;
  height: .13em;
  background: linear-gradient(90deg, transparent, rgba(255, 45, 120, .7) 18%, rgba(255, 45, 120, .7) 82%, transparent);
  filter: blur(1.4px);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform var(--dur-3) var(--ease-out);
}
.ink.show::after { transform: scaleX(1); }

/* 名字與卷宗標題的墨滲（懸停觸發） */
.dossier h1 { position: relative; }
.dossier h1::before {
  content: '';
  position: absolute;
  left: 0; bottom: -6px;
  width: 0; height: 2px;
  background: linear-gradient(90deg, var(--pink), rgba(255, 45, 120, 0));
  filter: blur(.6px);
  transition: width var(--dur-4) var(--ease-out);
}
.dossier:hover h1::before { width: 62%; }

/* ---------------------------------------------- 朱印多態 */
/* 朱印內容固定三行：狀態 / 檔號 / 附註，避免長文案撐破方框 */
.seal-mark {
  /* 原是 86px：实测为标题行高(38px)的 2.5 倍，视觉重心压过标题。
     收到 68px 后约为标题行高的 1.8 倍，主次关系正常。 */
  width: 68px;
  height: 68px;
  font-size: var(--fs-3xs);
  line-height: var(--lh-tight);
  letter-spacing: .04em;
  flex-direction: column;
}
.seal-mark .seal-no {
  display: block;
  margin: 1px 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0;
  opacity: .85;
}
.seal-mark .seal-sub {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  letter-spacing: .08em;
  opacity: .75;
}
/* 未完成：朱印偏轉、缺角 */
.seal-mark.seal-draft {
  border-style: dashed;
  opacity: .58;
  transform: rotate(-13deg);
}
/* 私密：雙框 */
.seal-mark.seal-private::before {
  content: '';
  position: absolute;
  inset: 3px;
  border: 1px solid var(--seal-soft);
  border-radius: 2px;
}

/* ---------------------------------------------- 卡片四角蕾絲角標 */
body.crosshatch .card::before,
.widget::before { transition: color var(--dur-2) var(--ease-std); }

/* 分類列的小十字 */
.term .term-count::before {
  content: '✚ ';
  font-size: var(--fs-2xs);
  opacity: .55;
}

/* ---------------------------------------------- 響應式 */
@media (max-width: 1400px) {
  .sidetab { display: none; }
}
@media (max-width: 900px) {
  .laceframe b { width: 52px; height: 52px; }
  .laceframe i { opacity: .34; }
  .ecg-strip { height: 50px; margin: var(--sp-6-5) 0; }
  .ecg-strip svg { top: 12px; }
}
@media (max-width: 720px) {
  .laceframe b { display: none; }
  .laceframe .lf-top, .laceframe .lf-bottom { height: 9px; background-size: 20px 9px; }
  .laceframe .lf-left, .laceframe .lf-right { width: 9px; background-size: 9px 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .ecg-strip svg { animation: none; }
  .sidetab::before { animation: none; }
  .ink::after { transition: none; }
}

/* ===== jirai-search.css ===== */
/* ============================================================
   jirai-search — 檢索台
   卡片目錄式的全屏搜索：輸入關鍵詞 → 逐條比對檔案
   ============================================================ */

/* ---------------------------------------------- 觸發按鈕 */
.search-btn {
  position: fixed;
  left: 18px;
  bottom: 62px;
  z-index: 951;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-h5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .16em;
  color: var(--pink);
  background: rgba(14, 8, 17, .88);
  border: 1px solid var(--line-pink);
  border-radius: 3px;
  backdrop-filter: blur(8px);
  cursor: pointer;
  transition: all var(--dur-1) var(--ease-std);
}
.search-btn:hover {
  color: #fff;
  box-shadow: 0 0 18px rgba(255, 45, 120, .3);
}
.search-btn kbd {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .06em;
  padding: 1px var(--sp-h1);
  color: var(--text-faint);
  border: 1px solid var(--line);
  border-radius: 2px;
}
.search-btn .ico { width: 12px; height: 12px; }

/* ---------------------------------------------- 檢索台本體 */
.search-mask {
  position: fixed;
  inset: 0;
  z-index: 9998;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 9dvh var(--sp-5) var(--sp-8);
  background: rgba(4, 2, 5, .74);
  backdrop-filter: blur(14px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .18s ease, visibility 0s .18s;
}
.search-mask.open { opacity: 1; visibility: visible; transition-delay: 0s; }

.search-panel {
  width: min(94vw, 720px);
  max-height: 78dvh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, rgba(20, 13, 23, .98), rgba(9, 6, 11, .98));
  border: 1px solid var(--line-pink);
  border-radius: 4px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, .65), 0 0 32px rgba(255, 45, 120, .08), inset 0 1px rgba(255, 220, 236, .06);
  transform: translateY(8px) scale(.99);
  transition: transform .24s var(--ease-out);
  overflow: hidden;
}
.search-mask.open .search-panel { transform: translateY(0) scale(1); }

/* 頂部：抽屜標籤 */
.search-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2-5);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: repeating-linear-gradient(45deg, rgba(255, 45, 120, .05) 0 8px, transparent 8px 16px);
}
.search-head .sh-title {
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  letter-spacing: .18em;
  color: var(--text-head);
}
.search-head .sh-title span { color: var(--seal, #c0392b); }
.search-head .sh-hint {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .14em;
  color: var(--text-faint);
}
.search-close {
  flex: none;
  /* 原为 24px：触屏媒体查询只在 pointer:coarse 下放大到 40px，桌面端偏小。
     它是模态框里唯一的关闭控件，统一提到 34px
     （桌面足够点中；触屏仍由 jirai-a11y.css 的 40px 规则接管）。 */
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--text-dim);
  cursor: pointer;
  transition: border-color .16s ease, background-color .16s ease, color .16s ease, transform .1s ease;
}
.search-close:hover { color: #fff; border-color: var(--pink); }
.search-close .ico { width: 11px; height: 11px; }

/* 輸入行 */
.search-input-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2-5);
  padding: var(--sp-3-5) var(--sp-4);
  border-bottom: 1px solid var(--line);
  transition: border-color .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.search-input-row:focus-within { border-bottom-color: rgba(255, 122, 184, .5); background-color: rgba(255, 45, 120, .025); box-shadow: inset 0 -1px rgba(255, 45, 120, .12); }
.search-clear { display: grid; place-items: center; flex: none; width: 32px; height: 32px; padding: 0; border: 1px solid var(--line); border-radius: 3px; color: var(--text-dim); background: transparent; cursor: pointer; }
.search-clear[hidden] { display: none; }
.search-clear:hover { color: #fff; border-color: var(--line-pink); }
.search-clear .ico { width: 12px; height: 12px; }
.search-input-row .si-prompt {
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--pink);
  text-shadow: 0 0 10px rgba(255, 45, 120, .7);
}
.search-input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  outline: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  letter-spacing: .04em;
  color: var(--text);
  caret-color: var(--pink);
}
.search-input::placeholder { color: var(--text-faint); letter-spacing: .08em; }

/* 結果列表 */
.search-body {
  min-height: 180px;
  min-width: 0;
  min-block-size: min(180px, 30dvh);
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.search-body::-webkit-scrollbar { width: 8px; }
.search-body::-webkit-scrollbar-thumb { background: rgba(255, 45, 120, .3); border-radius: 4px; }

.sr-item {
  display: block;
  padding: var(--sp-3) var(--sp-4) var(--sp-h5);
  border-bottom: 1px solid rgba(46, 32, 51, .8);
  text-decoration: none;
  cursor: crosshair;
  border-left: 2px solid transparent;
  transition: background-color .16s ease, border-color .16s ease;
}
.sr-item:hover,
.sr-item.active {
  background-color: rgba(255, 122, 184, .045);
  border-left-color: var(--pink-soft);
  text-shadow: none;
}
.sr-top {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2-5);
  flex-wrap: wrap;
}
.sr-no {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .1em;
  color: #c0392b;
  opacity: .9;
}
.sr-date {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--text-faint);
}
.sr-type {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .1em;
  color: var(--text-faint);
  padding: 1px var(--sp-1-5);
  border: 1px solid var(--line);
  border-radius: 2px;
}
.sr-title {
  margin: var(--sp-h1) 0 0;
  font-family: var(--font-head);
  font-size: var(--fs-base);
  letter-spacing: .04em;
  color: #ddd3e3;
  line-height: 1.55;
  overflow-wrap: anywhere;
}
.sr-item:hover .sr-title,
.sr-item.active .sr-title { color: #fff; }
.sr-snippet {
  margin: var(--sp-1-5) 0 0;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: #b9adc2;
  word-break: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sr-item mark {
  color: #fff;
  background: rgba(255, 45, 120, .34);
  border-radius: 2px;
  padding: 0 var(--sp-0-5);
  box-shadow: 0 0 8px rgba(255, 45, 120, .4);
}
.sr-meta {
  margin-top: var(--sp-1-5);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .04em;
  line-height: 1.7;
  overflow-wrap: anywhere;
  color: var(--text-faint);
}
.sr-meta .sr-sep { margin: 0 var(--sp-1-5); color: var(--line-pink); }

.search-empty,
.search-idle {
  padding: var(--sp-8) var(--sp-5);
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .08em;
  color: var(--text-dim);
  line-height: 2;
}
.search-empty strong { display: block; margin-bottom: 8px; color: var(--text-head); font-family: var(--font-head); font-size: 16px; font-weight: 400; overflow-wrap: anywhere; }
.search-retry { margin-top: 14px; min-height: 36px; padding: 6px 16px; color: var(--pink-soft); background: rgba(255, 45, 120, .06); border: 1px solid var(--line-pink); border-radius: 3px; cursor: pointer; }
.search-status:empty { display: none; }
.search-status:not(:empty)::before { content: ' · '; }
.search-idle .si-big {
  display: block;
  margin-bottom: var(--sp-2-5);
  font-family: var(--font-head);
  font-size: var(--fs-base);
  letter-spacing: .22em;
  color: rgba(255, 122, 184, .75);
}
.search-query-example { display: block; margin-top: 8px; color: var(--text-head); letter-spacing: .04em; }
.search-key-hint { display: block; margin-top: 14px; opacity: .7; }

.search-foot {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-h3) var(--sp-4);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .14em;
  color: var(--text-faint);
}
.search-foot .sf-count { color: var(--pink); }

/* ---------------------------------------------- 字級控制 */
.type-btn {
  position: fixed;
  left: 18px;
  bottom: 102px;
  z-index: 951;
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font-head);
  font-size: var(--fs-xs);
  letter-spacing: .12em;
  color: var(--text-dim);
  background: rgba(14, 8, 17, .88);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(8px);
  cursor: pointer;
  transition: all var(--dur-1) var(--ease-std);
}
.type-btn:hover { color: #fff; border-color: var(--line-pink); }
.type-btn b { color: var(--pink); font-weight: 400; }

/* 三檔字級：靠 html 上的 data-type 切換 */
html[data-type="s"] { --reading-scale: .94; }
html[data-type="m"] { --reading-scale: 1; }
html[data-type="l"] { --reading-scale: 1.1; }
html[data-type="xl"] { --reading-scale: 1.22; }

.post-body {
  font-size: calc(var(--fs-md) * var(--reading-scale, 1));
  /* 放大字級時行高同步放寬，否則大字配小行距會太擠 */
  line-height: calc(var(--lh-body) + (var(--reading-scale, 1) - 1) * .35);
}
.cab-title { font-size: calc(var(--fs-base) * var(--reading-scale, 1)); }

/* ---------------------------------------------- 響應式 */
@media (max-width: 720px) {
  .search-mask { padding: 16px var(--sp-3) max(16px, env(safe-area-inset-bottom, 0px)); }
  .search-panel { max-height: calc(100dvh - 32px - env(safe-area-inset-bottom, 0px)); }
  .search-input { font-size: 16px; }
  .search-idle, .search-empty { padding: 28px 18px; }
  .search-head .sh-hint { display: none; }
  .search-close { margin-left: auto; width: 44px; height: 44px; }
  .search-key-hint { display: none; }
  .search-foot > span:last-child { display: none; }
  .search-clear { min-width: 40px; min-height: 40px; }
  .search-btn kbd { display: none; }   /* 小螢幕不提示快捷键 */
  .sr-item { padding: var(--sp-h4) var(--sp-3-5); }
  .sr-title { font-size: var(--fs-base); }
}

@media (prefers-reduced-motion: reduce) {
  .search-mask, .search-panel { transition: none; }
}

/* ===== jirai-toolbar.css ===== */
/* ============================================================
   jirai-toolbar — 收拢後的浮動控件
   把原本散落的 6 個獨立浮動層整合成兩組：
     右下：歸位 + 繁體切換
     左下：檢索 + 字級 + 氛圍音
   目的不是少功能，而是少「各自為政的固定層」。
   ============================================================ */

/* ---------------------------------------------- 右下按鈕組 */
.toolbar {
  position: fixed;
  right: 18px;
  bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  z-index: 952;
  display: flex;
  align-items: stretch;
  background: rgba(14, 8, 17, .9);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(8px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .45);
  overflow: hidden;
}
.tb-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-h1);
  min-width: 38px;
  padding: var(--sp-h3) var(--sp-h4);
  font-family: var(--font-head);
  font-size: var(--fs-xs);
  letter-spacing: .1em;
  color: var(--text-dim);
  background: transparent;
  border: 0;
  border-left: 1px solid var(--line);
  cursor: pointer;
  transition: color .16s ease, background-color .16s ease, transform .1s ease, opacity .18s ease;
}
.tb-btn:first-child { border-left: 0; }
.tb-btn:hover { color: #fff; background: rgba(255, 45, 120, .12); }
.tb-btn .ico { width: 13px; height: 13px; }
.tb-btn[aria-pressed="true"] {
  color: #fff;
  background: rgba(192, 57, 43, .2);
}

/* 「歸位」只在滚过一屏后出现，初始不占视觉 */
#to-top { opacity: 0; visibility: hidden; max-width: 0; min-width: 0; padding-left: 0; padding-right: 0; }
#to-top.show { opacity: 1; visibility: visible; max-width: 60px; min-width: 38px; padding-left: var(--sp-h4); padding-right: var(--sp-h4); }

/* ---------------------------------------------- 左下按鈕組 */
/* 檢索 / 字級 / 氛圍音 由各自的 partial 產出，這裡統一外觀與位置 */
.search-btn,
.type-btn,
.ambient {
  position: static;
  border-radius: 0;
  border: 0;
  border-left: 1px solid var(--line);
  background: transparent;
  backdrop-filter: none;
  box-shadow: none;
}
.search-btn { border-left: 0; }

.dock {
  position: fixed;
  left: 18px;
  bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  z-index: 952;
  display: flex;
  align-items: stretch;
  background: rgba(14, 8, 17, .9);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(8px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .45);
  overflow: hidden;
}
.dock .search-btn,
.dock .type-btn,
.dock .ambient {
  display: flex;
  align-items: center;
  gap: var(--sp-h2);
  padding: var(--sp-h3) var(--sp-3);
  font-size: var(--fs-xs);
  letter-spacing: .14em;
  color: var(--text-dim);
  transition: color .16s ease, background-color .16s ease, transform .1s ease;
}
.dock .search-btn:hover,
.dock .type-btn:hover,
.dock .ambient:hover { color: #fff; background: rgba(255, 45, 120, .12); }
.dock .search-btn { color: var(--pink); }
.dock .search-btn .ico { width: 12px; height: 12px; }
.dock .type-btn b { color: var(--pink); font-weight: 400; font-family: var(--font-head); }
.dock .ambient[aria-pressed="true"] { color: #fff; background: rgba(255, 45, 120, .18); }

/* ---------------------------------------------- 舊的獨立定位由 .dock 覆寫
   舊類別（.to-top / .variant-btn / .search-btn / .type-btn / .ambient）
   的 position/left/bottom 規則仍存在於各自檔案，這裡以更高的具體度壓掉。 */
.toolbar .tb-btn,
.dock .search-btn,
.dock .type-btn,
.dock .ambient {
  position: static;
  inset: auto;
  width: auto;
  height: auto;
  margin: 0;
}

/* ---------------------------------------------- 回應式 */
@media (max-width: 900px) {
  /* 小畫面只留檢索與字級，氛圍音收進面板以免擠爆 */
  .dock .ambient { display: none; }
}

@media (max-width: 720px) {
  .toolbar, .dock { right: 12px; left: auto; bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  .dock { left: 12px; right: auto; }
  .dock .search-btn,
  .dock .type-btn { padding: var(--sp-2) var(--sp-2-5); font-size: var(--fs-2xs); }
  .dock .search-btn span { display: none; }   /* 只留圖示，省寬度 */
  .dock .search-btn .ico { width: 14px; height: 14px; }
  .tb-btn { min-width: 34px; padding: var(--sp-2) var(--sp-h3); }
}

/* ===== jirai-keys.css ===== */
/* ============================================================
   jirai-keys — 檔案館键盘導覽样式
   跳檔号对话框 / 快捷键一览 / 底部位置提示
   全部沿用檔案館语言：等宽字、斜纹抽屉头、朱印色强调
   ============================================================ */

/* ---------------------------------------------- 跳檔号（G） */
.kn-jump {
  position: fixed;
  inset: 0;
  z-index: 9997;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 18vh var(--sp-5) var(--sp-8);
  background: rgba(4, 2, 5, .82);
  backdrop-filter: blur(8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-2) var(--ease-std), visibility var(--dur-2) var(--ease-std);
}
.kn-jump.open { opacity: 1; visibility: visible; }

.kn-jump__panel {
  width: min(92vw, 420px);
  background: linear-gradient(180deg, rgba(34, 23, 42, .99), rgba(14, 8, 18, .99));
  border: 1px solid var(--line-pink);
  border-radius: 3px;
  box-shadow: 0 0 60px rgba(255, 45, 120, .22), 0 20px 50px rgba(0, 0, 0, .6);
  transform: translateY(-10px) scale(.985);
  transition: transform var(--dur-3) var(--ease-out);
  overflow: hidden;
}
.kn-jump.open .kn-jump__panel { transform: translateY(0) scale(1); }

.kn-jump__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: repeating-linear-gradient(45deg, rgba(255, 45, 120, .07) 0 8px, transparent 8px 16px);
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  letter-spacing: .18em;
  color: var(--text-head);
}
.kn-jump__x {
  margin-left: auto;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--text-dim);
  font-size: var(--fs-xs);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-std), border-color var(--dur-1) var(--ease-std);
}
.kn-jump__x:hover { color: #fff; border-color: var(--pink); }
.kn-jump__x:active { transform: scale(.92); }

.kn-jump__row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
}
.kn-jump__prompt {
  font-family: var(--font-mono);
  font-size: var(--fs-xl);
  color: var(--seal, #c0392b);
  letter-spacing: .04em;
}
.kn-jump__input {
  flex: 1;
  min-width: 0;
  padding: var(--sp-2) 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line-pink);
  outline: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xl);
  letter-spacing: .18em;
  color: var(--text);
  caret-color: var(--pink);
}
.kn-jump__input::placeholder { color: var(--text-faint); letter-spacing: .12em; font-size: var(--fs-base); }
.kn-jump__input.shake-soft { animation: kn-shake var(--dur-3) var(--ease-shake); }
@keyframes kn-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-2px); }
  80% { transform: translateX(2px); }
}

.kn-jump__hint {
  padding: 0 var(--sp-4) var(--sp-4);
  min-height: 2.4em;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .1em;
  line-height: 1.6;
  color: var(--text-mute);
}
.kn-jump__hint.is-ok { color: var(--pink-soft); }
.kn-jump__hint.is-bad { color: var(--bad); }

/* ---------------------------------------------- 快捷键一览（?） */
.kn-help {
  position: fixed;
  inset: 0;
  z-index: 9997;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6vh var(--sp-5);
  background: rgba(4, 2, 5, .86);
  backdrop-filter: blur(8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-2) var(--ease-std), visibility var(--dur-2) var(--ease-std);
}
.kn-help.open { opacity: 1; visibility: visible; }

.kn-help__panel {
  width: min(92vw, 460px);
  background: linear-gradient(180deg, rgba(23, 16, 28, .99), rgba(14, 8, 18, .99));
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: 0 0 60px rgba(255, 45, 120, .18), 0 20px 50px rgba(0, 0, 0, .6);
  transform: scale(.985);
  transition: transform var(--dur-3) var(--ease-out);
  overflow: hidden;
}
.kn-help.open .kn-help__panel { transform: scale(1); }

.kn-help__head {
  display: flex;
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: repeating-linear-gradient(45deg, rgba(255, 45, 120, .06) 0 8px, transparent 8px 16px);
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  letter-spacing: .2em;
  color: var(--text-head);
}
.kn-help__x {
  margin-left: auto;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--text-dim);
  font-size: var(--fs-xs);
  cursor: pointer;
}
.kn-help__x:hover { color: #fff; border-color: var(--pink); }

.kn-help__list { margin: 0; padding: var(--sp-4); }
.kn-help__item {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  padding: var(--sp-2) 0;
  border-bottom: 1px dashed rgba(53, 38, 61, .8);
}
.kn-help__item:last-child { border-bottom: 0; }
.kn-help__item dt { flex: none; min-width: 74px; margin: 0; }
.kn-help__item dd {
  margin: 0;
  font-size: var(--fs-sm);
  letter-spacing: .04em;
  color: var(--text-dim);
}
.kn-help__item kbd {
  display: inline-block;
  padding: var(--sp-0-5) var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--pink-soft);
  background: rgba(255, 45, 120, .10);
  border: 1px solid rgba(255, 45, 120, .30);
  border-radius: 2px;
}
.kn-help__foot {
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .16em;
  color: var(--text-mute);
}

/* ---------------------------------------------- 底部位置提示 */
.kn-hint {
  position: fixed;
  left: 50%;
  bottom: 22px;
  z-index: 950;
  display: flex;
  align-items: center;
  gap: var(--sp-1-5);
  padding: var(--sp-h2) var(--sp-3);
  transform: translate(-50%, 10px);
  opacity: 0;
  visibility: hidden;
  background: rgba(14, 8, 18, .92);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(8px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
  transition: opacity var(--dur-3) var(--ease-out),
              transform var(--dur-3) var(--ease-out),
              visibility var(--dur-3) var(--ease-std);
  pointer-events: none;
}
.kn-hint.is-on { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.kn-hint.is-gone { display: none; }
.kn-hint.is-edge { border-color: var(--line-pink); }
.kn-hint kbd {
  padding: var(--sp-0-5) var(--sp-1-5);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--pink-soft);
  background: rgba(255, 45, 120, .10);
  border: 1px solid rgba(255, 45, 120, .28);
  border-radius: 2px;
}
.kn-hint__t {
  margin-right: var(--sp-1-5);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: .12em;
  color: var(--text-mute);
}

/* ---------------------------------------------- 响应式
   触屏没有物理键盘，隐藏提示；对话框本身仍可用（通过检索台入口）。 */
@media (hover: none), (max-width: 720px) {
  .kn-hint { display: none; }
}
@media (max-width: 720px) {
  .kn-jump { padding: 12vh var(--sp-4) var(--sp-x1); }
  .kn-jump__prompt, .kn-jump__input { font-size: var(--fs-lg); }
  .kn-help { padding: 4vh var(--sp-4); }
  .kn-help__item { gap: var(--sp-3); }
  .kn-help__item dt { min-width: 62px; }
}

@media (prefers-reduced-motion: reduce) {
  .kn-jump, .kn-help, .kn-jump__panel, .kn-help__panel, .kn-hint { transition: none; }
  .kn-jump__input.shake-soft { animation: none; }
}

/* ===== jirai-reveal.css ===== */
/* ============================================================
   jirai-reveal — 入场编排
   现状：页面所有块级内容瞬间出现，缺少「被逐份取出」的节奏。
   檔案館的隐喻适合有节制的错落入场：不是弹跳，是像翻到下一张卡片。

   ── 实现演进（两次失败都记录在此，避免后人重走）──
   方案 A（失败）：JS 加 .rv 隐藏 → 下帧加 .rv-in 触发 transition。
     实测无过渡：.rv 由 defer 脚本在文档解析后（实测 ~295ms）才加上，
     此时元素已以 opacity:1 渲染过，浏览器认为计算样式未变，过渡被跳过。
     受控实验证实：立即加类 → 无过渡；先强制布局再加类 → 保留起始值。
   方案 B（成功）：CSS @keyframes + animation-delay 做错落。
     动画从类被加上即执行，不依赖 transition 的状态变更。
   方案 C（本版）：再加 @starting-style，消除方案 B 残留的闪动 ——
     类在 295ms 才加上，之前元素已渲染为不透明，会出现「显示→隐藏→淡入」。
     @starting-style 让「元素首次渲染」本身成为过渡起点，与类何时加上无关。

   ── 一个必须记住的坑 ──
   CSS.supports('opacity','starting-style') 返回 false（特性检测写法本身是错的），
   但 CSSStartingStyleRule 已被正常解析。我一度据此写了
   @supports not (opacity: starting-style) 保护块 —— 结果它在支持的浏览器上
   命中，把元素强制设为 opacity:1，静默禁用了动画。已删除。
   @starting-style 只影响动画起点，特性不支持时最坏情况是退化为直接显现，
   不需要额外保护。

   ── 动效约束 ──
     - 只编排首屏可见元素（JS 判定），滚动后的内容直接呈现
     - 错落 24ms、上限 6 级
     - prefers-reduced-motion 下完全关闭
     - 只做 opacity + 6/10px 位移，不缩放，避免长文页面抖动
   ============================================================ */

/* 首屏元素从第一帧就是隐藏的 —— 配合 @starting-style 平滑进入。
   这条规则消除了「已渲染为可见、稍后才被隐藏」的闪动。 */
html.reveal-on .cabinet-head,
html.reveal-on .cabinet .cab-row,
html.reveal-on .dossier,
html.reveal-on .side .widget,
html.reveal-on .page-title {
  opacity: 0;
}

/* 淡入 + 上移：@starting-style 提供起始值 */
html.reveal-on .cabinet-head,
html.reveal-on .cabinet .cab-row,
html.reveal-on .dossier,
html.reveal-on .side .widget,
html.reveal-on .page-title {
  transition:
    opacity .32s var(--ease-out),
    transform .32s var(--ease-out),
    background-color .18s ease,
    box-shadow .18s ease;
  transition-delay: calc(var(--rv-i, 0) * 24ms), calc(var(--rv-i, 0) * 24ms), 0s, 0s;
  opacity: 1;
  transform: translateY(0);
}
@starting-style {
  html.reveal-on .cabinet-head,
  html.reveal-on .cabinet .cab-row,
  html.reveal-on .dossier,
  html.reveal-on .side .widget,
  html.reveal-on .page-title {
    opacity: 0;
    transform: translateY(6px);
  }
}

/* 侧栏 widget 从右侧靠入，与主栏的向上入场形成方向差 */
@media (min-width: 1100px) {
  @starting-style {
    html.reveal-on .side .widget { transform: translateX(8px); }
  }
}

/* 幕布：整页淡入，避免入场时先闪一帧 */
html.reveal-on .wrap { animation: rv-curtain .32s var(--ease-out) both; }
@keyframes rv-curtain {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  html.reveal-on .cabinet-head,
  html.reveal-on .cabinet .cab-row,
  html.reveal-on .dossier,
  html.reveal-on .side .widget,
  html.reveal-on .page-title {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  html.reveal-on .wrap { animation: none !important; }
}

/* ===== jirai-a11y.css ===== */
/* ============================================================
   jirai-a11y — 可访问性补强
   1. 键盘焦点可见（WCAG 2.4.7）—— 全站原本 0 个焦点样式
   2. 弱化文字对比度提升到小字可读标准
   3. 触控目标最小尺寸
   4. 强制色模式 / 高对比度适配
   ============================================================ */

/* ---------------------------------------------- 1. 焦点可见
   不做 :focus-visible 的降级——只要浏览器支持就用它，
   避免鼠标点击时出现描边；不支持则回退到 :focus。 */
:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 2px;
  border-radius: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}
/* 键盘用户在深色背景上需要更醒目的落点 */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px rgba(255, 45, 120, .22);
}
/* 输入框：描边 + 内发光，不用 outline 更贴合盒子形状 */
.search-input:focus-visible {
  outline: none;
}

/* ---------------------------------------------- 2. 对比度
   .footer 原为 3.32:1、.meta-row 为 4.43:1，小字下均不达标。
   深色背景上把弱化文字提到 ≥4.5:1，同时保留层级差。 */
.footer        { color: var(--text-mute); }   /* 约 5.6:1 */
.footer a      { color: #b9adc2; }
.meta-row      { color: var(--text-mute); }
.card-meta     { color: var(--text-mute); }
.cab-date      { color: var(--text-mute); }
.cab-type      { color: var(--text-mute); }
.ch-meta       { color: var(--text-mute); }
.profile .motto { color: var(--text-mute); }
.profile-updated { color: #b98fae; }
.profile-foot  { color: var(--text-mute-2); }
.sr-meta       { color: var(--text-mute); }
.search-foot   { color: var(--text-mute); }
.search-head .sh-hint { color: var(--text-mute); }
.search-idle   { color: var(--text-mute); }
.cabinet-foot  { color: var(--text-mute); }
.widget-list .n { color: var(--text-mute-2); }
.profile-stats .l { color: var(--text-mute); }

/* 极小的装饰性文字（9px 以下）本就不承载信息，只用于图形化标签，
   这里保证它们至少可辨认，不再进一步压暗。 */
.ecg-lead, .ecg-bpm, .seal-sub, .footer::after { opacity: 1; }

/* ---------------------------------------------- 3. 触控目标
   移动端把过小的可点区域撑到 44px 最小高度（WCAG 2.5.8） */
@media (pointer: coarse) {
  .tag-chip,
  .tag-cloud a,
  .widget-list a,
  .cab-row,
  .term,
  .post-nav a {
    min-height: 44px;
  }
  .widget-list li { padding: var(--sp-1) 0; }
  .search-close { width: 40px; height: 40px; }
  .nav-toggle { min-width: 44px; min-height: 44px; }
  .brand { min-height: 44px; }
  .dock .search-btn,
  .dock .type-btn,
  .dock .ambient,
  .tb-btn { min-width: 44px; min-height: 44px; }
}

/* 正文里的行内链接给足垂直热区（不改变视觉） */
.post-body p a {
  padding: var(--sp-0-5) 0;
}

/* ---------------------------------------------- 4. 强制色模式
   Windows 高对比度 / forced-colors 下，背景图与伪元素装饰会失效，
   这里保证内容仍然可读、边框仍然可见。 */
@media (forced-colors: active) {
  .laceframe, .sidetab, .grain, .halo-layer, .particles,
  .med-cursor, .danger-veil, .spark, .lm-blast, .name-heart { display: none !important; }
  .card, .widget, .term, .cabinet, .table-wrap { border: 1px solid CanvasText; }
  .ribbon { border-bottom: 1px solid CanvasText; }
  a, button { forced-color-adjust: auto; }
  .tag-chip, .cab-type { border: 1px solid CanvasText; }
}

/* ---------------------------------------------- 5. 按下反馈（:active）
   审计发现全站 :hover 有 27 个选择器、:active 有 0 个 ——
   点击时没有任何物理反馈，鼠标与触屏都觉得「按了个寂寞」。
   这里统一补一套：位移用 transform（不触发重排，长文页面也不会抖动），
   表面变化用 --bg-raise，颜色变化用高亮。

   ⚠ 绝不可让这些规则命中 <html> 或 <body>：
   根元素一旦有了 transform，就会成为所有 position:fixed 元素的包含块，
   于是固定定位全部失效（工具栏、左下按钮组、位置提示会瞬间跳到文档流位置）。
   本站有两处同名冲突要特别小心：
     - .boot-skip 既是开屏按钮的类名，也是加在 <html> 上的状态类
       （jirai-boom.js:26 / layout.ejs:10），故这里用 #boot-skip 指定按钮。
     - .card-more / .rail-item 等若日后被加到根元素上，同样会引发此问题。
   判断方法：按下鼠标后检查 getComputedStyle(document.documentElement).transform
   是否变成非 none —— 若是，说明某条 :active 命中了根元素。 */

#boot-skip:active,
.dock .search-btn:active,
.dock .type-btn:active,
.dock .ambient:active,
.tb-btn:active,
.nav-toggle:active,
.search-close:active,
.toast-x:active,
.pager a:active,
.toc-inner .toc-link:active,
.tag-chip:active,
.tag-cloud a:active,
.card-more:active,
.post-nav a:active,
.widget-list a:active,
.rail-item a:active {
  transform: translateY(1px) scale(.985);
  transition-duration: var(--dur-1);
}

/* 表面型控件：按下时加深底色，比缩放更贴合物件感 */
.tb-btn:active,
.dock .search-btn:active,
.dock .type-btn:active,
.dock .ambient:active,
.pager a:active,
.post-nav a:active,
.widget-list a:active {
  background-color: var(--bg-raise);
}

/* 档案行、条目卡、检索结果：按下时整行下沉并提亮 */
.cab-row:active,
.term:active,
.sr-item:active {
  transform: translateY(1px);
  background: rgba(255, 45, 120, .10);
}
.cab-row:active::before,
.term:active::before { opacity: 1; }

/* 卡片：只用表面变化，不做缩放（卡片面积大，缩放会显得整页在抖） */
.card:active {
  border-color: var(--line-pink);
  background: linear-gradient(180deg, var(--bg-card-2), var(--bg-card));
}

/* 正文链接：按下时虚线变实线，像被按进去 */
.post-body p a:active {
  border-bottom-style: solid;
  color: #fff;
}

/* 触屏没有 hover，但必须保留 active —— 否则手机点击毫无反馈 */
@media (hover: none) {
  .dock .search-btn:active,
  .dock .type-btn:active,
  .tb-btn:active,
  .tag-chip:active,
  .cab-row:active { background-color: var(--bg-raise); }
}

/* ---------------------------------------------- 6. 减少动效
   已有部分 reduce 规则分散在各文件，这里补全兜底：
   保留颜色/表面变化（不影响理解），去掉持续动画与位移。 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .grain, .halo-layer i, .particles, .ribbon-track { animation: none !important; }
  *:active { transform: none !important; }   /* 按下位移也去掉，只留颜色变化 */
}
