/* ===== css/main/40-art.css —— 艺术层：大标题邮戳 / 留言卡微旋转 / 图钉 / 印章锤动画 / 间距重排 / 字体颜色 =====
   · 2026-10-16 从 index.html 的 <style> 按【原顺序】切出：只切不重构，样式一个字符没改
   · 加载顺序（必须保持）：00-tokens → 10-layout → 20-components → 30-themes → 40-art
   · 本文件是第 5／5 段；删掉头部这 5 行，剩下的就是原文对应片段
   ===== */
    /* ============================================================
       【本轮新增 2026-10-07】第二小步：视觉母题（邮戳 + 便签墙质感）
       三件事，全部只动"皮肤"，零 HTML 结构改动、零 JS 改动、零接口改动：
         A. 大标题邮戳：CSS 伪元素画的圆形邮戳（"已寄出"），呼应公告栏信封母题；
         B. 留言卡微旋转：像便签贴上墙，悬停回正；
         C. 交错浮入：前 8 张卡片依次延迟入场（自带"落定"动画，动画终点 =
            静态倾斜角，结束零跳变；「加载更多」追加的卡片从第 9 张起零延迟）。
       稳定性设计：
         1) 本段全部是追加规则，不修改上方任何既有规则；整段删除即可完全还原；
         2) 只动 transform / opacity / box-shadow，不动 display / 尺寸 / 排版流，
            不会引起横向滚动或布局位移；
         3) 邮戳 pointer-events:none 绝不挡点击；极窄屏(≤340px)自动隐藏；
         4) 配色全部用 currentColor / 主题无关的中性阴影 → 紫霞/秋意/盛夏自动适配；
         5) 段末自带 prefers-reduced-motion 保险：系统"减弱动效"开启时，
            本段新增的动画/旋转/过渡全部关闭（必须排在本段最后才能覆盖生效）。
       ============================================================ */

    /* ---------- A. 大标题邮戳（纯 CSS 伪元素，无新 DOM） ---------- */
    .page-title {
      position: relative; /* 仅作为邮戳的定位基准，不影响文字排版 */
    }

    .page-title::after {
      content: '已寄出';
      position: absolute;
      top: -16px;
      right: 6%;
      width: 62px;
      height: 62px;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid currentColor;
      outline: 1px solid currentColor;
      outline-offset: -7px;          /* 内圈细环，做出邮戳的双圈感 */
      border-radius: 50%;
      color: currentColor;
      opacity: 0.45;
      font-family: var(--font-display);
      font-size: 12px;
      font-weight: 600;
      letter-spacing: 2px;
      text-indent: 2px;              /* 抵消 letter-spacing 的右偏，保证视觉居中 */
      transform: rotate(-14deg);
      pointer-events: none;          /* 纯装饰，绝不挡点击 */
    }

    /* 极窄屏：邮戳可能贴近标题文字，直接收起（纯装饰，无信息损失） */
    @media (max-width: 340px) {
      .page-title::after { display: none; }
    }

    /* ---------- B. 留言卡微旋转（便签贴墙质感）+ 悬停回正 + 红色图钉 ---------- */
    .message-item {
      position: relative;        /* 图钉的定位基准（本轮新增，不影响布局流） */
      transition: transform 0.25s ease, box-shadow 0.25s ease;
    }

    /* 红色图钉：像便签被钉在墙上，钉头压在卡片左上角、上半截露出卡外。
       径向渐变做出高光球面感 + 下方投影做出"钉进去"的立体感。
       纯装饰：pointer-events:none 绝不挡点击；随卡片一起微微旋转。 */
    .message-item::before {
      content: '';
      position: absolute;
      top: -5px;
      left: 14px;
      width: 12px;
      height: 12px;
      border-radius: 50%;
      background: radial-gradient(circle at 35% 30%, #ff9a9a 0%, #e25555 48%, #a83232 100%);
      box-shadow: 0 3px 4px rgba(70, 25, 25, 0.35), 0 1px 1px rgba(0, 0, 0, 0.18);
      pointer-events: none;
    }

    /* 每张卡带一点随机感的小倾斜（3 张一循环，肉眼像随机；本轮按反馈略加大） */
    .message-item:nth-of-type(3n+1) {
      transform: rotate(-0.9deg);
      animation: msgInTiltA 0.5s ease-out backwards; /* backwards：延迟期间保持透明，防闪现 */
    }
    .message-item:nth-of-type(3n+2) {
      transform: rotate(0.75deg);
      animation: msgInTiltB 0.5s ease-out backwards;
    }
    .message-item:nth-of-type(3n) {
      transform: rotate(-0.5deg);
      animation: msgInTiltC 0.5s ease-out backwards;
    }

    /* 悬停：回正 + 轻浮起（有过渡，不突兀；触屏设备点按后无副作用） */
    .message-item:hover {
      transform: rotate(0deg) translateY(-2px);
      box-shadow: 0 6px 18px rgba(0, 0, 0, 0.10);
    }

    /* ---------- C. "落定"关键帧：透明度 + 上滑 + 旋转三合一 ---------- */
    /* from 的角度刻意与 to 不同 → 像便签被"啪"地贴上墙再微微摆正
       （本轮随静态倾斜加大同步调整，终点仍 = 静态倾斜角，零跳变） */
    @keyframes msgInTiltA {
      from { opacity: 0; transform: translateY(12px) rotate(0.9deg); }
      to   { opacity: 1; transform: translateY(0) rotate(-0.9deg); }
    }
    @keyframes msgInTiltB {
      from { opacity: 0; transform: translateY(12px) rotate(-1.1deg); }
      to   { opacity: 1; transform: translateY(0) rotate(0.75deg); }
    }
    @keyframes msgInTiltC {
      from { opacity: 0; transform: translateY(12px) rotate(1.2deg); }
      to   { opacity: 1; transform: translateY(0) rotate(-0.5deg); }
    }

    /* 交错节奏：第 2~8 张每张延迟 60ms；第 9 张起（「加载更多」追加的）零延迟 */
    .message-item:nth-of-type(2) { animation-delay: 0.06s; }
    .message-item:nth-of-type(3) { animation-delay: 0.12s; }
    .message-item:nth-of-type(4) { animation-delay: 0.18s; }
    .message-item:nth-of-type(5) { animation-delay: 0.24s; }
    .message-item:nth-of-type(6) { animation-delay: 0.3s; }
    .message-item:nth-of-type(7) { animation-delay: 0.36s; }
    .message-item:nth-of-type(8) { animation-delay: 0.42s; }
    .message-item:nth-of-type(n+9) { animation-delay: 0s; }

    /* ---------- D. 减弱动效保险（排在本段最后，覆盖上面所有新增规则） ---------- */
    @media (prefers-reduced-motion: reduce) {
      .message-item,
      .message-item:nth-of-type(n) {
        animation: none;
        transform: none;
        transition: none;
      }
    }

    /* ---------- E. 图钉立体化 2.0【本轮新增】 ----------
       目标：把上一版"贴片感的扁圆"升级为现实中书店留言墙那种、
       从右下角看上去的真图钉——
         · 光源定在左上（与卡片阴影方向一致）：
           钉头左上是月牙高光 + 一个锐利小反光点，
           右下沉入暗红（inset 阴影做出球面）；
         · 一根金属针从钉头右下侧斜插进纸面（看得见"钉进去"的过程）；
         · 针尖处有纸面被压出的小暗痕；
         · 纸面上有一片投向右下的柔和投影（影子方向 = 背光方向）。
       层级：钉头(z:2)压住针身顶端(z:1)，针像从"头底下"钻出来。
       安全性：尺寸只比旧版大 2~3px 且贴着左上角，不遮挡文字与相邻卡片；
       pointer-events:none 保持，绝不挡点击。
       回滚方式：整段删除即回到上一版圆点图钉（上面的旧块无需动）。 */

    /* 钉头：球体感（覆盖旧版样式，靠后出现即生效） */
    .message-item::before {
      top: -6px;
      left: 13px;
      width: 14px;
      height: 14px;
      z-index: 2;
      background:
        /* 锐利小反光点（玻璃感/塑料感的高光芯） */
        radial-gradient(2.5px 2px at 30% 25%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0) 100%),
        /* 球面主渐变：左上亮红 → 右下深红 */
        radial-gradient(circle at 32% 26%,
          #ffd9d9 0%, #ff9d9d 20%, #e35555 50%, #b03535 76%, #8a2424 100%);
      box-shadow:
        inset -2.5px -3px 4px rgba(96, 12, 12, 0.5),   /* 球面右下暗部（立体感的钥匙） */
        inset 1.5px 2px 3px rgba(255, 255, 255, 0.5),  /* 左上环境反光 */
        0 4px 5px rgba(70, 25, 25, 0.35),              /* 投在纸上的落影 */
        0 1px 1px rgba(0, 0, 0, 0.15);
      transition: transform 0.25s ease;                /* 配合悬停的轻微"按压"反馈 */
    }

    /* 针身 + 入针暗痕 + 纸面投影：一个伪元素、三层背景一次画完 */
    .message-item::after {
      content: '';
      position: absolute;
      top: -2px;
      left: 18px;
      width: 14px;
      height: 14px;
      z-index: 1;                        /* 压在钉头之下：针从"头底下"钻出来 */
      pointer-events: none;
      background:
        /* 1) 入针暗痕：针尖扎进纸面的小暗点 */
        radial-gradient(closest-side, rgba(80, 30, 30, 0.32), rgba(80, 30, 30, 0) 72%),
        /* 2) 针身：金属细针，从钉头右下斜插向纸面 */
        linear-gradient(45deg,
          rgba(0, 0, 0, 0) 43%, #dcdce2 46%, #a2a2ab 50%, #6f6f78 54%, rgba(0, 0, 0, 0) 57%),
        /* 3) 纸面投影：投向右下的柔和椭圆影 */
        radial-gradient(closest-side, rgba(70, 25, 25, 0.17), rgba(70, 25, 25, 0) 78%);
      background-size: 8px 6px, 12px 12px, 17px 7px;
      background-position: 7px 10px, 2px 3px, -1px 8px;
      background-repeat: no-repeat;
    }

    /* 悬停时钉子轻微放大：像被轻轻按了一下（与卡片回正同时发生，很克制） */
    .message-item:hover::before {
      transform: scale(1.06);
    }

    /* 减弱动效：图钉的悬停过渡也一并关掉（纯装饰，不影响信息） */
    @media (prefers-reduced-motion: reduce) {
      .message-item::before { transition: none; }
      .message-item:hover::before { transform: none; }
    }
    /* ---------- E2. 图钉 2.2：针角 60°、去掉褶皱【本轮新增·覆盖 2.1】 ----------
       反馈：2.1 有两个问题——
         ① 针立到近 96° 后，钉头和针身错位，球看着像"脱臼"往左歪；
         ② 入针褶皱和纯白色留言卡片不搭。
       本轮改动（钉头完全沿用 2.0，一个像素都不挪）：
         · 针身角度定为 60°（比 2.0 的 45° 更立、又不至于竖直）；
           针身起点对准 2.0 钉头中心 (20,1) 的正下方，向右下 60° 插入纸面，
           球、针、入针点重新连成一条直线，不再错位；
         · 入针暗痕仍画在最上层罩住针尖，针身下端止于入针点（沿用 2.1 的修法）；
         · 删除 2.1 的纸张褶皱（conic 折痕 + 鼓包光晕整层拿掉），回归纯净白卡。
       层级、pointer-events、悬停反馈均沿用 2.0。
       回滚方式：删除本段即回到 2.0（上一段 E 不用动）。 */

    /* 针身(60°) + 入针暗痕 + 纸面投影：仍然一个伪元素画完；
       钉头不再有覆盖规则，完全沿用上一段 E 的 2.0 位置（top -6 / left 13） */
    .message-item::after {
      top: -2px;
      left: 18px;
      width: 16px;
      height: 17px;
      background:
        /* 1) 入针暗痕：最上层，半透明暗孔罩住针尖，针像"扎进"纸里（深浅与 2.0 一致） */
        radial-gradient(closest-side, rgba(80, 30, 30, 0.32), rgba(80, 30, 30, 0) 72%),
        /* 2) 针身：60° 斜插，从钉头底下钻出，下端止于入针点 */
        linear-gradient(60deg,
          rgba(0, 0, 0, 0) 43%, #dcdce2 46%, #a2a2ab 50%, #6f6f78 54%, rgba(0, 0, 0, 0) 57%),
        /* 3) 纸面投影：仍投向右下（跟随背光方向），与 2.0 相同 */
        radial-gradient(closest-side, rgba(70, 25, 25, 0.17), rgba(70, 25, 25, 0) 78%);
      background-size: 8px 6px, 12px 12px, 17px 7px;
      background-position: 5px 11px, 0px 3px, -1px 8px;
      background-repeat: no-repeat;
    }

    /* ---------- F. 先看后写：邀请留言小弹窗【本轮新增 2026-10-09】 ----------
       毛玻璃小卡片，出现在屏幕底部居中；z-index 500——
       高于正文（30~40），低于公告弹窗(8000)/长文(8500)/阅读器(8600)/引导页(9999)。
       纯展示：出现/消失全靠 hidden 属性切换，无 JS 动画依赖，弱设备零压力。 */
    .cta-toast {
      position: fixed;
      left: 50%;
      bottom: 22px;
      transform: translateX(-50%);
      width: calc(100% - 32px);
      max-width: 360px;
      z-index: 500;
      padding: 14px 44px 14px 18px;
      background: rgba(255, 255, 255, 0.92);
      -webkit-backdrop-filter: blur(10px);
      backdrop-filter: blur(10px);
      border-radius: 14px;
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16), 0 2px 6px rgba(0, 0, 0, 0.08);
      animation: ctaToastIn 0.4s ease-out;
    }

    .cta-toast-text {
      margin: 0 0 10px;
      font-size: 14px;
      line-height: 1.6;
      color: #4a4a55;
    }

    .cta-toast-button {
      display: inline-block;
      border: none;
      border-radius: 999px;
      padding: 8px 18px;
      font-size: 14px;
      font-weight: 600;
      color: #fff;
      background: linear-gradient(135deg, #a18cd1, #c58ad8);
      cursor: pointer;
      transition: transform 0.2s ease, box-shadow 0.2s ease;
    }

    .cta-toast-button:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(161, 140, 209, 0.4);
    }

    .cta-toast-button:active {
      transform: translateY(0);
    }

    /* 右上角小关闭按钮：绝对定位在卡片角上，不占排版 */
    .cta-toast-close {
      position: absolute;
      top: 6px;
      right: 6px;
      width: 26px;
      height: 26px;
      border: none;
      border-radius: 50%;
      background: transparent;
      color: #9a9aa5;
      font-size: 13px;
      line-height: 1;
      cursor: pointer;
      transition: background 0.2s ease, color 0.2s ease;
    }

    .cta-toast-close:hover {
      background: rgba(0, 0, 0, 0.06);
      color: #55555f;
    }

    @keyframes ctaToastIn {
      from { opacity: 0; transform: translateX(-50%) translateY(14px); }
      to   { opacity: 1; transform: translateX(-50%) translateY(0); }
    }

    /* 减弱动效：弹窗直接出现，不做动画（其余元素动效同样沿用既有降级） */
    @media (prefers-reduced-motion: reduce) {
      .cta-toast { animation: none; }
      .cta-toast-button,
      .cta-toast-close { transition: none; }
    }

    /* 主题微调：仅文字颜色跟随主题，底色保持中性毛玻璃白（三主题都和谐） */
    body[data-theme="autumn"] .cta-toast-text { color: #6b5c49; }
    body[data-theme="summer"] .cta-toast-text { color: #4e6b5c; }

    /* ---------- G. 邮戳显隐修复【本轮新增 2026-10-09】 ----------
       原状：邮戳是纯 CSS 伪元素无条件显示——从没寄过留言的全新访客也顶着
       「已寄出」邮戳（bug）。只评论的客户同样不该有（评论从不发放令牌）。
       修法：默认隐藏；body 带上 stamp-posted 类时伪元素才恢复内容。
       该类由 JS 按现有门禁令牌判定（令牌只在主留言发表成功后签发一次）。
       追加式：不改动上方原始 .page-title::after；删除本块 + JS 挂钩即可完全还原。 */
    body:not(.stamp-posted) .page-title::after {
      content: none;
    }

    /* ---------- H. 印章锤入场动画【本轮新增 2026-10-11 初版】 ----------
       预研结论落地：纯 CSS keyframes + 少量 JS 编排，零依赖零图片（锤子为内嵌 SVG 木色哑光）。
       v1 范围（角度/时长/缓动等细节后续按观感再打磨）：
         1) 舞台 .stamp-hammer-stage：绝对定位于 .page-title 内，坐标与邮戳伪元素完全一致
            （top -16px / right 6% / 62×62）——锤子以邮戳位置定位，印下的就是「已寄出」本体；
         2) 锤子：左侧入场 → 悬停蓄力 → 盖下 → 压实停留 → 右后方离场（单条 keyframes，2.4s）；
         3) 盖下瞬间（约 1.05s）邮戳伪元素做「印章落纸」（scale 1.8→1、淡入至 0.45，
            动画终点 = 既有静态样子，结束零跳变）；
         4) 稳定性：舞台 pointer-events:none；z-index 45（仅压过调色板面板 40，远低于弹窗 8000+）；
            动画只用 transform/opacity（GPU 合成层不卡帧）；2.6s 后 JS 移除舞台，零残留；
            prefers-reduced-motion 整体跳过；JS 全程 try/catch，任何异常只是"这次没动画"。
    */
    .stamp-hammer-stage {
      position: absolute;
      top: -16px;
      right: 6%;
      width: 62px;
      height: 62px;
      z-index: 45;
      pointer-events: none;
      /* 【v3】3D 透视：从左后方看印章（rotateY 正角 = 左侧朝向观者，
         与留言卡小红钉的视角刚好互为镜像） */
      perspective: 560px;
    }

    .stamp-hammer {
      position: absolute;
      left: 50%;
      top: -20px;
      width: 54px;
      height: 67px;
      margin-left: -27px;
      transform-origin: 50% 88%;
      transform-style: preserve-3d;
      will-change: transform, opacity;
      animation: stampHammerPlay 2.4s ease-in-out both;
    }

    /* 【v4 编舞】拿笔角度入场：印章像手里握着的笔一样——章体倾斜约 16°（顶向右，
       与照片里持笔的倾角一致），从正上方斜插降下（不再从左边横穿），落到悬停位后
       微抬蓄力、边回正边垂直盖下（rotateZ 归零 = 底面放平压实，角度不错），
       压实停留后照旧抬起右上优雅离场。rotateY(20°) 左后方 3D 视角全程保持。 */
    @keyframes stampHammerPlay {
      0%   { transform: translate(-24px, -120px) rotateY(22deg) rotateZ(16deg); opacity: 0; }
      12%  { opacity: 1; }
      30%  { transform: translate(0, 0) rotateY(20deg) rotateZ(16deg); }       /* 斜角降到悬停位 */
      38%  { transform: translate(0, -6px) rotateY(20deg) rotateZ(10deg); }    /* 微抬,开始回正 */
      46%  { transform: translate(0, 12px) rotateY(20deg) rotateZ(0deg); }     /* 回正+垂直盖下（印下瞬间） */
      60%  { transform: translate(0, 11px) rotateY(20deg) rotateZ(0deg); }     /* 压实停留 */
      78%  { transform: translate(34px, -24px) rotateY(24deg) rotateZ(7deg); opacity: 1; }
      100% { transform: translate(96px, -52px) rotateY(30deg) rotateZ(14deg); opacity: 0; }  /* 离场 */
    }

    /* 【v3】地面投影：光源在右上方 → 影子落在底面左下方。
       悬停时影子大而淡（离纸远），盖下时收拢变实（贴纸），离场随之散去——3D 感的关键。 */
    .stamp-shadow {
      position: absolute;
      left: 50%;
      top: 48px;
      width: 58px;
      height: 13px;
      margin-left: -29px;
      border-radius: 50%;
      background: radial-gradient(ellipse at center, rgba(40, 26, 12, 0.45), rgba(40, 26, 12, 0) 70%);
      animation: stampShadowPlay 2.4s ease-in-out both;
      will-change: transform, opacity;
    }

    @keyframes stampShadowPlay {
      0%, 18% { opacity: 0;    transform: translateX(-6px) scale(1.25); }
      30%     { opacity: 0.22; transform: translateX(-6px) scale(1.15); }
      38%     { opacity: 0.2;  transform: translateX(-6px) scale(1.2); }
      46%     { opacity: 0.5;  transform: translateX(-3px) scale(1); }
      60%     { opacity: 0.5;  transform: translateX(-3px) scale(1); }
      80%     { opacity: 0.12; transform: translateX(-6px) scale(1.2); }
      100%    { opacity: 0;    transform: translateX(-6px) scale(1.25); }
    }

    /* 盖下瞬间：邮戳本体「印章落纸」 */
    body.stamp-ink .page-title::after {
      animation: stampInkIn 0.45s ease-out 1.02s both;
    }

    @keyframes stampInkIn {
      0%   { opacity: 0;    transform: rotate(-14deg) scale(1.8); }
      55%  { opacity: 0.55; transform: rotate(-14deg) scale(0.96); }
      100% { opacity: 0.45; transform: rotate(-14deg) scale(1); }
    }

    /* 减弱动效：整体跳过（不出现锤子，邮戳直接以静态出现） */
    @media (prefers-reduced-motion: reduce) {
      .stamp-hammer-stage { display: none; }
      body.stamp-ink .page-title::after { animation: none; }
    }

    /* ============================================================
       【本轮新增 2026-10-13】桌面端（≥601px）流畅度优化
       为什么：手机端早有一套「毛玻璃降级」，桌面端反而保留 backdrop-filter；
               而背景还有两个持续漂浮的柔光粒子（每帧都在改变"被模糊的内容"）
               → 浏览器每一帧都要重做大范围背景模糊：滚动、卡片淡入就会掉帧。
       做什么（只换"实现方式"，颜色/排版/层级/文案一律不变）：
         ① .container 毛玻璃 → 稍实的纯色底（与手机端同一套观感，只是把 600px 断点反过来）
         ② 柔光粒子去掉冗余的 blur(60px)（径向渐变本身已经是柔光；漂浮动画保留）
         ③ 引导页 / 封禁页的整屏毛玻璃 → 纯色半透明底（与手机端一致）
       不做什么：不动动画时长、不动 z-index、不动任何 JS；≤600px 手机端一个字不改。
       还原：整段删除即可（删掉本注释块与下面整个 @media 块）。
       ============================================================ */
    @media (min-width: 601px) {
      .container {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background-color: rgba(255, 255, 255, 0.95);
      }
      body[data-theme="autumn"] .container { background-color: rgba(255, 252, 245, 0.95); }
      body[data-theme="summer"] .container { background-color: rgba(238, 244, 239, 0.95); }

      .intro-overlay {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background-color: rgba(20, 12, 40, 0.9);
      }
      body[data-theme="autumn"] .intro-overlay { background-color: rgba(48, 32, 18, 0.92); }
      body[data-theme="summer"] .intro-overlay { background-color: rgba(26, 52, 42, 0.92); }

      .ban-overlay {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
      }

      /* 柔光粒子：去掉大半径 blur（观感几乎无差，省掉每帧的模糊合成） */
      body::before,
      body::after {
        filter: none;
      }
    }

    /* ============================================================
       【本轮新增 2026-10-13】留言字体选择（工具栏 + 面板 + 留言字体样式）
       为什么三块写在一起：都只服务「留言字体」这一个功能；整段删除即可完全还原。
       位置：工具栏在「留言内容编辑框」与「提交留言大按钮」之间（见 HTML 的 .compose-tools）。
       后续扩展：要加「字体颜色」等按钮，往 .compose-tools 里再放一个同款按钮即可。
       安全性：全部是"只加不改"的新规则，只碰颜色/字体/尺寸，不涉及 display 开关与层级冲突
              （面板 z-index 45，高于正文 30~40，低于公告弹窗 8000 / 引导页 9999）。
       ============================================================ */
    :root {
      /* 可选字体：加新字体 = 这里加一行 + 面板加一个按钮 + JS 白名单加一个值 */
      --compose-font-wenkai: var(--font-display);   /* 与页面大标题同款（霞鹜文楷 → 本机楷体 → 系统字体） */
      --compose-font-songti: 'Songti SC', 'STSong', 'SimSun', '宋体', 'Noto Serif SC', serif;
      /* 按钮文字：纯白 #fff 在浅底上很扎眼 → 换成柔和白（约 90% 亮度），护眼 */
      --compose-btn-text: #e7ece8;
    }

    /* ① 提交按钮文字：纯白 → 柔和白（只改字色，渐变底与尺寸一律不动） */
    .submit-button { color: var(--compose-btn-text); }

    /* ② 工具栏：编辑框与提交按钮之间；position: relative 作为字体面板的定位基准 */
    .compose-tools {
      position: relative;
      display: flex;
      align-items: center;
      gap: 8px;
      margin: 10px 0;
    }

    /* ③ 小长方形按钮：长度约整行的 1/5；高度比点赞胶囊（13px + 5px 内边距）略小 */
    .compose-tool-button {
      width: 20%;
      min-width: 76px;    /* 极窄屏兜底：「留言字体」四个字仍完整 */
      max-width: 132px;   /* 宽屏兜底：不逼近点赞胶囊的观感体量 */
      padding: 4px 10px;
      border: none;
      border-radius: 9px; /* 小长方形（刻意不用胶囊圆角） */
      background: var(--theme-accent);  /* 跟随调色板所选主题色 */
      color: var(--compose-btn-text);
      font-size: 12px;
      font-weight: 600;
      letter-spacing: 1px;
      line-height: 1.6;
      font-family: inherit;
      cursor: pointer;
      transition: transform 0.2s ease, box-shadow 0.2s ease;
    }
    .compose-tool-button:hover { transform: translateY(-1px); }
    .compose-tool-button:active { transform: scale(0.98); }
    .compose-tool-button.is-active { box-shadow: 0 0 0 2px var(--theme-accent-soft); }
    .compose-tool-button:focus-visible { outline: 2px solid var(--theme-accent); outline-offset: 2px; }

    /* ④ 字体面板：与调色板面板同款变量/圆角/阴影；向下展开，
          盖住下方提交按钮而不是编辑框 → 边选字体边看编辑中的文字 */
    .font-panel {
      position: absolute;
      left: 0;
      right: 0;
      top: calc(100% + 6px);
      z-index: 45;
      padding: 8px 10px;
      border: 1px solid var(--theme-panel-border);
      border-radius: 14px;
      background: var(--theme-panel-bg);
      box-shadow: var(--theme-panel-shadow);
      -webkit-backdrop-filter: blur(10px);
      backdrop-filter: blur(10px);
      animation: palettePop 0.18s ease-out;
    }
    .font-panel[hidden] { display: none !important; }

    .font-panel-head { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
    .font-panel-title { font-size: 11px; font-weight: 700; letter-spacing: 0.8px; color: var(--theme-panel-title); }
    .font-panel-hint { font-size: 9.5px; letter-spacing: 0.3px; color: var(--theme-panel-text); }
    .font-panel-close {
      margin-left: auto;
      padding: 1px 8px;
      border: none;
      border-radius: 999px;
      background: var(--theme-accent-soft);
      color: var(--theme-accent);
      font-size: 11px;
      font-family: inherit;
      cursor: pointer;
    }

    /* 三张字体卡：名字用"自己那套字体"显示 → 一眼看到效果 */
    .font-options { display: flex; gap: 7px; }
    .font-option {
      flex: 1 1 0;
      min-width: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 2px;
      padding: 6px;
      border: 1px solid var(--theme-option-border);
      border-radius: 10px;
      background: var(--theme-option-bg);
      font-family: inherit;
      cursor: pointer;
      transition: transform 0.2s ease, box-shadow 0.2s ease;
    }
    .font-option:hover { transform: translateY(-1px); }
    .font-option:active { transform: scale(0.98); }
    .font-option.is-active { border-color: var(--theme-accent); box-shadow: 0 0 0 2px var(--theme-accent-soft); }
    .font-option-name { font-size: 13px; font-weight: 700; color: var(--theme-option-name); white-space: nowrap; }
    .font-option-desc { font-size: 9.5px; letter-spacing: 0.2px; color: var(--theme-option-desc); white-space: nowrap; }
    .font-option[data-font-value="wenkai"] .font-option-name { font-family: var(--compose-font-wenkai); }
    .font-option[data-font-value="songti"] .font-option-name { font-family: var(--compose-font-songti); }

    /* ⑤ 编辑区实时预览：选哪套字体，昵称框 + 留言框立刻跟着变 */
    form[data-compose-font="wenkai"] #nickname,
    form[data-compose-font="wenkai"] #message { font-family: var(--compose-font-wenkai); }
    form[data-compose-font="songti"] #nickname,
    form[data-compose-font="songti"] #message { font-family: var(--compose-font-songti); }

    /* ⑥ 已发出去的留言卡片：按留言保存的字体渲染（昵称 + 正文一起变） */
    .message-item.msg-font-wenkai .message-nickname,
    .message-item.msg-font-wenkai .message-content { font-family: var(--compose-font-wenkai); }
    .message-item.msg-font-songti .message-nickname,
    .message-item.msg-font-songti .message-content { font-family: var(--compose-font-songti); }

    /* 窄屏：按钮按比例略放大一点（仍远小于提交按钮），面板照旧铺满整行 */
    @media (max-width: 600px) {
      .compose-tool-button { width: 26%; min-width: 72px; }
    }

    /* ⑦ 【本轮调整 2026-10-13】间距重排：字体按钮「贴住编辑区下部」，与提交大按钮拉开
       改前：编辑框底边距 22px + 工具栏上下各 10px → 按钮离编辑框/红字远、离提交按钮近；
       改后：编辑框底边距 22→8px、工具栏 8px 上 / 18px 下 →
             · 字体按钮紧贴「编辑框（或字数超额红字提示）」，只留 8px 呼吸位；
             · 与提交大按钮之间留 18px，视觉上归到「编辑区」，不再黏着提交按钮；
             · 整体高度比改前少约 8px → 提交按钮自然略上移一点。
       注意：红字提示 .len-tip 是编辑器内部的普通流元素（margin-top 6px，JS 插在输入框后面），
             本段**没有**改它的任何属性，只调它外面的容器底边距 → 既不遮挡也不挤压它。
       要还原：删掉本段三条规则即可。 */
    .content-field { margin-bottom: 8px; }
    .compose-tools { margin: 8px 0 18px; }
    .len-tip { margin: 6px 0 0; }   /* 显式写死，防止日后有人改容器样式时被顺手带偏 */

    /* ⑧ 【本轮新增 2026-10-14】字体颜色（3 个主题色）+ 两个弹窗统一缩小约 10%
       基准：改前「留言字体」弹窗实测 608×87（860px 视口）；现在宽高各收约 10%。
       做法：① 两个面板共用同一套类名与尺寸（保证"两个一致"）；② 内边距/字号/间距各收一档；
             ③ 宽度 100% → 90%（左右各留 5%，居中，观感更秀气）。
       还原：删掉本段（⑧）即可，字体与颜色功能本身不受影响。 */
    .font-panel {
      left: 5%;
      right: auto;
      width: 90%;
      padding: 7px 9px;
      border-radius: 13px;
    }
    .font-panel-head { margin-bottom: 4px; }
    .font-panel-title { font-size: 10px; }
    .font-panel-hint { font-size: 9px; }
    .font-panel-close { padding: 1px 7px; font-size: 10px; }
    .font-options { gap: 6px; }
    .font-option { padding: 5px; min-height: 42px; }
    .font-option-name { font-size: 12px; line-height: 1.25; }
    .font-option-desc { font-size: 9px; line-height: 1.25; }

    /* 颜色卡：圆点 + 两行文字（横向排布；与字体卡等高等宽 → 两个面板总高一致） */
    .color-option {
      flex-direction: row;
      align-items: center;
      gap: 6px;
      text-align: left;
    }
    .color-option-text {
      display: flex;
      flex-direction: column;
      gap: 1px;
      min-width: 0;
    }
    .color-dot {
      flex: none;
      width: 16px;
      height: 16px;
      border-radius: 50%;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.85), 0 1px 3px rgba(40, 30, 70, 0.22);
    }
    /* 三个颜色 = 调色板里的三个主题色，原样照搬 */
    .color-dot-default { background: linear-gradient(135deg, #6b6b6b 0%, #333333 100%); }
    .color-dot-purple  { background: #5931F6; }
    .color-dot-autumn  { background: #b26a17; }
    .color-dot-summer  { background: #4f9d6b; }

    /* 编辑区实时预览：选了颜色，昵称框 + 留言框里的字立刻跟着变色 */
    form[data-compose-color="purple"] #nickname,
    form[data-compose-color="purple"] #message { color: #5931F6; }
    form[data-compose-color="autumn"] #nickname,
    form[data-compose-color="autumn"] #message { color: #b26a17; }
    form[data-compose-color="summer"] #nickname,
    form[data-compose-color="summer"] #message { color: #4f9d6b; }

    /* 已发出去的留言卡片：按留言保存的颜色渲染（昵称 + 正文一起变）；
       本段在主题色规则之后、同优先级时后者胜 → 自定义颜色能盖住主题默认文字色 */
    .message-item.msg-color-purple .message-nickname,
    .message-item.msg-color-purple .message-content { color: #5931F6; }
    .message-item.msg-color-autumn .message-nickname,
    .message-item.msg-color-autumn .message-content { color: #b26a17; }
    .message-item.msg-color-summer .message-nickname,
    .message-item.msg-color-summer .message-content { color: #4f9d6b; }

  