
/* ================= 浮动购物车（右下角，需求 9 的唯一入口） ================= */
.cs-floating-cart-wrap{position:fixed;bottom:24px;right:24px;width:56px;height:56px;z-index:9999}
.cs-floating-cart-wrap > .cs-floating-cart{position:absolute!important;bottom:0!important;right:0!important;top:auto!important;left:auto!important}
/* 飞入落点反馈 */
.cs-floating-cart.is-bump{animation:cs-cart-bump .62s cubic-bezier(.34,1.56,.64,1)}
@keyframes cs-cart-bump{0%{transform:scale(1)}35%{transform:scale(1.28)}60%{transform:scale(.94)}100%{transform:scale(1)}}

/* 飞入的「幽灵」元素 */
.cs-fly-ghost{border-radius:10px;object-fit:cover;background:#f5f5f7;box-shadow:0 10px 26px rgba(0,0,0,.16)}

/* ================= 悬停浮层（需求 6） =================
   ⚠️ 显式写 `box-sizing:border-box`：站内没有统一 `*{box-sizing}`（MEMORY 有记录），
      默认 content-box 下 width:340px 实测外框变成 374px（340 + 16×2 padding + 1×2 border）。

   🔴🔴 第六十轮（2026-09-25）宽度 340 → **420**，手机安全护栏 32 → 24：
      340px 时内容区实测只剩 220px（＝420 之前），而一行要装
      「缩略图 42 + 间距 10 + 元信息（−/+ 步进器 88 + 血条 116 + 价格 60）+ × 24」
      ⇒ 元信息被压到 220，血条被迫参与收缩（`.cs-trow` 撞 min-width ⇒ 轨道只剩 **9px**，
      看着就像「血条不见了」），价格也被挤到第二行。
      420px 下内容区 ≈ 285 ⇒ **血条、价格与步进器能同处一行**，不再相互挤。
      手机端同步放宽（`calc(100vw - 24px)`）——护栏从 32 降到 24，只是把两侧留白各让 4px，
      保证 320px 机仍然不溢出。
      ⚠️ 改宽度只动这一处：抽屉是 `position:absolute; right:0` 挂在浮动车按钮上，
        没有别处按 340 做过绝对定位换算（已全库 grep 核对）。 */
.cs-cart-pop{box-sizing:border-box;position:absolute;bottom:calc(100% + 14px);right:0;width:min(420px,calc(100vw - 24px));max-height:60vh;overflow:auto;background:#fff;border:1px solid #e5e5e5;border-radius:14px;box-shadow:0 18px 44px rgba(0,0,0,.16);padding:14px 16px 16px;opacity:0;visibility:hidden;transform:translateY(8px);transition:opacity .18s ease,transform .18s ease,visibility .18s ease;text-align:left;z-index:10000}
/* 🔴 显隐**只**由 JS 打/摘 `data-open` 决定，这里**不再**写 `:hover`.
   理由：「浮层本身就是 JS 建的」⇒ 没有 JS 连 `.cs-cart-pop` 这个元素都不存在，
   CSS `:hover` 省不下任何兜底，只会引入第二套状态（两套状态一冲突就是
   「点一下开、再点一下合不上」）。
   尤其是触摸端：Chrome / Safari 点一下会留下**黏性 hover**，第二次点图标想合上时
   会被 `:hover` 顶着合不掉。 */
.cs-cart-pop[data-open="1"]{opacity:1;visibility:visible;transform:translateY(0)}
/* 🔴 按钮与浮层之间那 14px 的空隙：鼠标从按钮移向 +/− 时如果穿过空隙，
   :hover 会在半路断掉、浮层当场收起（加了加减键之后这就成了硬伤）。
   铺一条透明「桥」把空隙盖住 —— 它属于 .cs-cart-pop，所以算在 hover 链里。 */
.cs-cart-pop::after{content:"";position:absolute;left:0;right:0;bottom:-14px;height:14px}
.cs-cart-pop-head{font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#8B1A1A;margin:0 0 10px}
.cs-cart-pop__list{list-style:none;margin:0;padding:0}
.cs-cart-pop__item{border-bottom:1px solid #f0f0f2}
/* ---- 可滑动的一行（需求 1）---- */
.cs-cart-pop__swipe{position:relative;overflow:hidden}
.cs-cart-pop__row{position:relative;z-index:1;display:flex;align-items:center;gap:10px;padding:9px 0;background:#fff;transition:transform .22s cubic-bezier(.16,1,.3,1)}
/* 右侧红色删除区：被上面那行盖住，行左移才露出（触摸端专属，桌面端 display:none） */
.cs-cart-pop__del{position:absolute;top:0;right:0;bottom:0;width:84px;display:none;align-items:center;justify-content:center;padding:0;border:0;background:#c8102e;color:#fff;font:inherit;font-size:13px;font-weight:600;cursor:pointer;letter-spacing:.01em}
.cs-cart-pop__del:active{background:#a50d26}
/* ============ 浮动购物车预览缩略图：1 / 1 → 3 / 4 ============
   🔴 2026-09-24 第五十三轮（日记口径 R53）· 用户需求：购物车缩略图**还是 1:1**，要 3:4。
   ⚠️ 本行原写「第五十二轮」是**笔误**：那次交付目录最终定名「第五十三轮」，
      改的是**浮动车浮层**（`cs-cart-pop__thumb`），不是购物车页行项目（后者一直是 3:4）。
   根因（浏览器实测，非猜测）——命中该 <img> 且声明 height 的规则只有两条：
     `.woocommerce img, .woocommerce-page img{height:auto;max-width:100%}`  ← 特异性 0-1-1
     `.cs-cart-pop__img{…height:42px…}`                                  ← 特异性 0-1-0
   ⇒ WooCommerce 自带那条**特异性更高**，把 height:42px 压掉 ⇒ 图片按自身
     600×800 比例涨成 42×56，而外层 `.cs-cart-pop__thumb` 仍是 42×42 +
     `overflow:hidden` ⇒ 用户看到的缩略图**是正方形**（且底部被裁掉一截）。
   ⇒ 修法：外层容器与内层图片**一起**改成 3:4；图片的 height 必须 `!important`
     （外部规则来自 WC，靠特异性赢不了；与第三十四轮处理推荐区时同一口径）。
     宽高比：42 : 56 = 0.750 = 3:4，与商品主图母版 1200×1600 一致 ⇒ 零裁切。
   ⚠️ 只动尺寸，不动圆角/背景/object-fit（`object-fit:cover` 保留，仍是等比裁切而非拉伸）。 */
.cs-cart-pop__thumb{flex:0 0 42px;width:42px;height:56px;border-radius:8px;overflow:hidden;background:#f5f5f7;display:block}
.cs-cart-pop__img{width:42px;height:56px!important;object-fit:cover;display:block;border-radius:8px}
.cs-cart-pop__img--ph{display:block;width:42px;height:56px;background:#ececf0;border-radius:8px}
.cs-cart-pop__meta{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:4px}
/* 1.7.2：`overflow-wrap:break-word` 让超长型号词（如 `Simplified-Chinese`）在必要时断行，
   不至于撑破 meta 把右侧价格顶出抽屉。只在「一个词比整行还宽」时才触发，正常文案不受影响。 */
.cs-cart-pop__name{font-size:13px;line-height:1.35;color:#1d1d1f;overflow-wrap:break-word}
/* ---- 1.4.0：商品名链接（点名字回商品页）----
   🔴 `color:inherit` + `text-decoration:none` ⇒ 静态观感与改前**逐像素一致**：
      链接默认的蓝紫色和下划线都不出现，手机上不会"看起来变了"。
   🔴 只在桌面 hover 变色；`-webkit-tap-highlight-color:transparent` 去掉 iOS/安卓
      点按时那层灰蓝高亮（与站点色不搭）。 */
.cs-cart-pop__namelink{color:inherit;text-decoration:none;display:inline;-webkit-tap-highlight-color:transparent;transition:color .15s ease}
.cs-cart-pop__namelink:hover{color:#8B1A1A}
.cs-cart-pop__namelink:focus-visible{outline:2px solid #8B1A1A;outline-offset:2px;border-radius:3px}
/* ⚠️ 档位标签 `.cs-cart-pop__var` **不需要**额外保色：它自己就声明了 `color`
   （`#6e6e73` / `--pre` 是 `#8B1A1A`），不继承父级 ⇒ hover 时不会跟着变红。
   这里**故意不写** `.cs-cart-pop__namelink:hover .cs-cart-pop__var{color:…}` —
   那条特异性 0-3-0 会压掉 `--pre` 的 `#8B1A1A`，把 Pre-Order 标签变灰。 */
/* ---- 1.7.2：数量区「尺寸硬固定」----
   🔴 根因（浏览器实测，非推测）：`.cs-cart-pop__step` 原来只写 `width:22px`，
      而 flex item 默认 `flex-shrink:1` ⇒ 这一行可用宽度一不足，浏览器就按比例
      压缩两个按钮。实测 320px 视口 + 数量 1000 时，step 由 22×22 被压成 **18.7×22**
      —— 这正是「加减号被挤压变形」的来源（价格越长、行内越挤，压得越狠）。
   🔴 另一半：`.cs-cart-pop__qn` 只给 `min-width:15px`，数字 1 位→3 位会自己变宽，
      ⇒ 同一行在不同数量下宽度不同，就是「排版随数量变化」的来源。
   ⇒ 口径：**按钮与数字都写成固定宽度**，弹性全部交给商品名那一行（它本来就会换行）。
      `flex:0 0 22px` = 不涨 / 不缩 / 基准 22px；再加 `min-width`+`max-width` 各钉一道，
      任何窄度、任何数量下都不可能再变形。
   ⚠️ 22px 是**含边框的实际渲染尺寸**（实测确认站点对 button 生效 border-box）；
      不要按 content-box 去补 2px，否则按钮会凭空胖一圈、与改前不逐像素。
   ⚠️ `font-variant-numeric:tabular-nums` 让 1 与 0 等宽 ⇒ 数量跳动时数字不会左右抖。 */
.cs-cart-pop__line{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:4px 8px;min-width:0}
.cs-cart-pop__qty{position:relative;display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;flex-wrap:nowrap;font-size:12px;color:#86868b;white-space:nowrap}
.cs-cart-pop__qn{flex:0 0 auto;min-width:26px;text-align:center;font-size:12.5px;font-weight:600;color:#1d1d1f;font-variant-numeric:tabular-nums}
.cs-cart-pop__step{flex:0 0 22px;width:22px;height:22px;min-width:22px;max-width:22px;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;padding:0;border:1px solid #d6d6db;border-radius:6px;background:#fff;color:#1d1d1f;font:inherit;font-size:13px;line-height:1;cursor:pointer;transition:border-color .15s ease,color .15s ease}
.cs-cart-pop__step:hover:not([disabled]){border-color:#8B1A1A;color:#8B1A1A}
.cs-cart-pop__step:focus-visible{outline:2px solid #8B1A1A;outline-offset:1px}
/* 到上下限就是**禁用态**（与 block cart 一致），不是把行删掉 */
.cs-cart-pop__step[disabled]{opacity:.38;cursor:default}
/* ---- 1.3.0：变体档位标签（现货=证书号 / 预售=Pre-Order）---- */
.cs-cart-pop__var{display:inline-block;margin-left:4px;padding:1px 6px;border-radius:5px;background:#f2f2f4;color:#6e6e73;font-size:10.5px;font-weight:600;letter-spacing:.02em;vertical-align:1px;white-space:nowrap}
.cs-cart-pop__var--pre{background:#fbeaea;color:#8B1A1A}
/* ---- 1.7.0：Pre-Order 气泡（弹出 ⇒ 停留 ⇒ 掉落到目标行）----
   🔴 位置与动画全部由 JS 用 **Web Animations API** 驱动（见 1.7.0 的 JS 段），
      这里只给静态观感 + 合成层提示。
   🔴 宿主是 `document.body` + `position:fixed` —— 原来的宿主（`.cs-cart-pop__qty` /
      `.wc-block-components-quantity-selector`）都落在 `overflow:auto` + `transform`
      的祖先里，气泡往下飞会被**裁掉**，所以必须挂到 body 上走视口坐标。
   🔴 仍然 `pointer-events:none`：不占位、不改变行高、不挡点击。真正的结果由服务端回包驱动
      （badge +1、多出一行 Pre-Order），气泡只是**说明**。 */
.cs-tip{position:fixed;left:0;top:0;z-index:100001;display:inline-block;padding:3px 8px;border-radius:999px;background:#8B1A1A;color:#fff;font-size:10.5px;font-weight:600;line-height:1.3;letter-spacing:.02em;white-space:nowrap;box-shadow:0 3px 10px rgba(139,26,26,.28);pointer-events:none;will-change:transform,opacity}
/* 1.7.2：金额**不参与**拉伸与压缩 ⇒ 数字再长也只会往右占位，不会回头去挤数量按钮。
   `margin-left:auto` 负责靠右；万一行宽真的不够、被 `flex-wrap` 折到第二行，
   它依然靠右（`justify-content:space-between` 对单元素不生效，它生效）。 */
.cs-cart-pop__price{flex:0 0 auto;margin-left:auto;font-size:13px;font-weight:600;color:#1d1d1f;white-space:nowrap}
/* 桌面端的删除键（触摸端被 CSS 换成红色滑出键） */
.cs-cart-pop__x{flex:0 0 auto;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:1px solid #e5e5e5;border-radius:999px;background:#fff;color:#86868b;font:inherit;font-size:14px;line-height:1;cursor:pointer;transition:color .15s ease,border-color .15s ease}
.cs-cart-pop__x:hover{color:#c8102e;border-color:#c8102e}
.cs-cart-pop__x:focus-visible,.cs-cart-pop__del:focus-visible{outline:2px solid #8B1A1A;outline-offset:1px}
.cs-cart-pop__item.is-busy{opacity:.5;pointer-events:none}
.cs-cart-pop__note{margin:8px 0 0;font-size:12px;line-height:1.4;color:#8B1A1A}
.cs-cart-pop__note[hidden]{display:none}
.cs-cart-pop__total{display:flex;justify-content:space-between;align-items:baseline;padding:12px 0 4px;font-size:14px;font-weight:600;color:#1d1d1f}
.cs-cart-pop__actions{display:flex;gap:8px;margin-top:10px}
.cs-cart-pop__btn{flex:1 1 0;text-align:center;text-decoration:none;font-size:13px;font-weight:600;padding:10px 12px;border-radius:9px;background:#8B1A1A;color:#fff;border:1.5px solid #8B1A1A;transition:opacity .15s ease}
.cs-cart-pop__btn:hover{opacity:.88;color:#fff}
.cs-cart-pop__btn--ghost{background:#fff;color:#1d1d1f;border-color:#d6d6db}
.cs-cart-pop__btn--ghost:hover{color:#8B1A1A;border-color:#8B1A1A;opacity:1}
.cs-cart-pop__empty{font-size:13px;color:#86868b;padding:6px 0 2px}
/* 触摸端：换成红色滑出删除键，并声明纵向留给页面滚动、横向留给滑删。
   ⚠️ 判据用 `hover:none and pointer:coarse`（**真的触摸设备**），不用视口宽度 ——
      窄窗口里的鼠标用户仍旧走 × 那一套，不至于「只能拖拽才能删」。 */
@media (hover:none) and (pointer:coarse){
	.cs-cart-pop__x{display:none}
	.cs-cart-pop__del{display:inline-flex}
	.cs-cart-pop__row{touch-action:pan-y}
}

/* ================= 一键 Buy 按钮（需求 1/2/4） ================= */
.cs-buy-wrap{display:flex;flex-direction:column;align-items:center;gap:6px;margin-bottom:1rem}
.cs-buy{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;min-width:132px;padding:11px 22px;border:1.5px solid #8B1A1A;border-radius:9px;background:#8B1A1A;color:#fff;font-family:inherit;font-size:14px;font-weight:600;line-height:1.2;cursor:pointer;appearance:none;-webkit-appearance:none;transition:opacity .15s ease,transform .12s ease}
.cs-buy:hover{opacity:.9}
.cs-buy:active{transform:scale(.98)}
.cs-buy:focus-visible{outline:2px solid #8B1A1A;outline-offset:2px}
.cs-buy[disabled],.cs-buy.is-busy{cursor:default;opacity:.72}
.cs-buy.is-added{background:#1d7a3d;border-color:#1d7a3d}
/* 🔴 2026-09-24 第三十三轮：单品页经典按钮（WC 自己渲染的 `.single_add_to_cart_button`）
   也走同一套状态类。⚠️ 站内 CSS 给 `.single_add_to_cart_button` 上了
   `background-color:#8B1A1A !important` ⇒ 这里必须同样 `!important` 才盖得住绿色。 */
.single_add_to_cart_button.is-busy{cursor:default;opacity:.72}
.single_add_to_cart_button.is-added{background:#1d7a3d!important;border-color:#1d7a3d!important}
.cs-buy__note{position:absolute;top:-9px;right:-6px;font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;background:#f5f5f7;color:#86868b;border:1px solid #e5e5e5;border-radius:999px;padding:2px 7px;line-height:1.4;pointer-events:none}
.cs-buy__toast{font-size:12px;line-height:1.45;color:#8B1A1A;text-align:center}

/* ================= 规格选择窗（需求 5，当前无实例） ================= */
.cs-choices{position:fixed;inset:0;z-index:100001;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.42);opacity:0;transition:opacity .18s ease}
.cs-choices.is-open{opacity:1}
.cs-choices__box{background:#fff;border-radius:16px;padding:22px;width:min(380px,calc(100vw - 40px));box-shadow:0 24px 60px rgba(0,0,0,.28);transform:translateY(10px);transition:transform .18s ease}
.cs-choices.is-open .cs-choices__box{transform:translateY(0)}
.cs-choices__title{font-size:16px;font-weight:600;color:#1d1d1f;margin:0 0 14px}
.cs-choices__group{margin:0 0 14px}
.cs-choices__label{display:block;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#8B1A1A;margin:0 0 8px}
.cs-choices__opts{display:flex;flex-wrap:wrap;gap:8px}
.cs-choices__opt{padding:9px 16px;border:1.5px solid #d6d6db;border-radius:8px;background:#fff;color:#1b1b1f;font:inherit;font-size:13px;font-weight:600;cursor:pointer}
.cs-choices__opt.is-active{background:#8B1A1A;border-color:#8B1A1A;color:#fff}
.cs-choices__foot{display:flex;gap:8px;margin-top:6px}
.cs-choices__foot .cs-buy{flex:1 1 0}
.cs-choices__cancel{flex:0 0 auto;padding:11px 16px;border:1.5px solid #d6d6db;border-radius:9px;background:#fff;color:#1d1d1f;font:inherit;font-size:14px;font-weight:600;cursor:pointer}

/* ================= 1.4.0 / 1.7.0：Cart 页（block cart）的「+ ⇒ Pre-Order」气泡 =================
   🔴 刻意**不**给解禁后的「+」加任何新样式：WC Blocks 自己有一套「enabled / disabled」样式，
      解禁后它自然就是正常的可点样子 —— 加自定义 hover 反而会与它打架、也和抽屉里那枚不像。
      气泡本体与抽屉**共用同一个类 `.cs-tip`**（见上面 1.7.0 那段），这里只多一条落点高亮。 */

/* ---- 1.7.0：气泡掉落到哪一行，那一行就轻亮一下 ----
   🔴 只动 `background-color`（不碰 padding / border / width）⇒ **零布局位移**，
      不会让表格重排、更不会让买家看到「跳一下」；与 1.6.0 的 `.cs-blk-added` 同款手法。
   ⚠️ 抽屉侧用它；Cart 页侧**不叠第二套** —— 那边复用 `blkMarkRow()` 的 `cs-blk-added`，
      同一元素上写两个 `animation` 会互相覆盖。 */
.cs-tip-land{animation:cs-tip-land .68s cubic-bezier(.16,1,.3,1) both}
@keyframes cs-tip-land{
	0%{background-color:rgba(139,26,26,.20)}
	55%{background-color:rgba(139,26,26,.11)}
	100%{background-color:rgba(139,26,26,0)}
}

/* ================= 1.6.0：接棒成功时「刚加好的那一行」 =================
   🔴 只动 `background-color`（不碰 padding / border / width）⇒ **零布局位移**，
      不会让表格重排、更不会让买家看到"跳一下"。
   🔴 用 `both` + JS 定时摘类：同一个 key 连点也能重播（JS 先 remove 再强制回流）。 */
.cs-blk-added{animation:cs-blk-add 1.4s cubic-bezier(.16,1,.3,1) both}
@keyframes cs-blk-add{
	0%{background-color:rgba(139,26,26,.14)}
	28%{background-color:rgba(139,26,26,.08)}
	100%{background-color:rgba(139,26,26,0)}
}
/* 点击已受理、正在等服务端：轻量"已收到"反馈。不给 `pointer-events:none`
   —— 双击闸在 JS 里（`blkQ`），这里只做视觉。 */
.wc-block-components-quantity-selector__button--plus[data-cs-busy="1"]{opacity:.5;cursor:progress}

@media (max-width:600px){
	.cs-floating-cart-wrap{bottom:18px;right:16px}
	.cs-buy{min-width:118px;padding:10px 18px;font-size:13.5px}
	/* 1.7.2：手机端把行内横向间距由 10 收到 8（一行 3 个 gap ⇒ 省 6px），
	   这 6px 全部让给商品名与数量区。**缩略图尺寸与字号一律不动**，
	   保证改前改后是同一种观感，只是「宽裕一点」。 */
	.cs-cart-pop__row{gap:8px}
}
@media (prefers-reduced-motion:reduce){
	.cs-cart-pop,.cs-floating-cart-wrap > .cs-floating-cart,.cs-cart-pop__row{transition:none}
	.cs-floating-cart.is-bump{animation:none}
	/* 1.7.0：气泡不做动画 —— 走 `tipFall()` 的 reduced-motion 分支（原地淡出 + 定时移除） */
	.cs-tip{transition:none}
	.cs-tip-land{animation:none}
	/* 1.6.0：不动画；高亮的类由 JS 侧一并跳过（`blkMarkRow` 里判 reduce） */
	.cs-blk-added{animation:none}
}
