/* ==========================================================================
   CardSpicy · 首页三条产品线展示区
   --------------------------------------------------------------------------
   设计口径（2026-09-21）：
   · 对标 chatcut 的「高科技简约」—— 无边框、少文字、大留白、灰阶为主
   · 参照 ATP /sample-shop/ 的交互 —— 顶部小切换按钮，悬停 160ms 防抖切换，
     内容 300ms 淡入上浮
   · 🔴 尺寸统一靠**同一个外框**，不靠逐张调图：
       .csx-frame 三块内容（真实照片 / 矢量产品板）共用同一内边距与圆角，
       .csx-art  固定 3:4 且固定留白 ⇒ 每一块板在三种线里一模一样大
   · 🔴 线条只用透明度不用固定灰（rgba(0,0,0,.08)）—— 固定灰在不同底色上对不齐
   · 🔴 去边框必须补「面」：外框底 #FAFAFA，#FFFFFF 上会直接消失
   · 红色只出现在「当前选中的那枚按钮」上，其余一律黑/灰
   · 1.3.0（2026-09-22）：产品板**价格下方**加了迷你 Buy。
     🔴 两条硬约束：① 只是**收小**，配色/圆角语言/交互态全部沿用 cs-cart-ux 的
     `.cs-buy`（改主色时这里自动跟着变）；② `.csx-tile` 因此从 `<a>` 变成容器 div，
     可点区域下移到 `.csx-link` —— 详见下面 .csx-tile / .csx-link 两段的注释。
   · 切换按钮**桌面等宽**（--csx-chip-w，三条线共用）—— 2026-09-22 加、
     2026-10-10（R258e）由 148px 收至 132px（首页整体小一档），
     改前宽度随标签长短变化（49–142px 差 2.9 倍）。手机上不用等宽，原因见文件末尾注释。
   ========================================================================== */

.csx-wrap {
	--csx-ink: #1d1d1f;
	--csx-ink2: #4a4a4f;
	--csx-muted: #86868b;
	--csx-hair: rgba(0, 0, 0, .08);
	--csx-hair-strong: rgba(0, 0, 0, .22);
	--csx-accent: #8B1A1A;
	--csx-surface: #FAFAFA;
	--csx-surface-hover: #F3F3F5;
	/* ⚠️ `--csx-tile` 已于 2026-09-22 删除：产品板宽度现在由 .csx-row 的
	   栅格列数 + --csx-gap 自动决定（每行 6/4/2 个），不再有固定板宽。 */
	--csx-gap: 18px;
	--csx-radius: 14px;
	/* 切换按钮的统一宽度。148px 是「最长标签 Storage & Binders（桌面 141px）+ 余量」定出来的，
	   三条线共用这一个值 ⇒ 三行按钮等宽、右缘与左起点都对齐。
	   ≤620px 改回 auto：手机上等宽装不下最长标签（详见下方响应式注释）。 */
	--csx-chip-w: 132px;   /* 🔴 2026-10-10 R258e：148→132（首页整体小一档，与二级页拉开层级） */
	--csx-ease: cubic-bezier(.16, 1, .3, 1);

	box-sizing: border-box;
	width: 100%;
	max-width: 1320px;
	margin: 0 auto;
	padding: 8px 24px 76px;
}
.csx-wrap *,
.csx-wrap *::before,
.csx-wrap *::after { box-sizing: border-box; }
.csx-wrap p { margin: 0; }

/* ---------------------------------------------------------------- 一条线 */
.csx-block { padding-top: 64px; }
.csx-block:first-child { padding-top: 24px; }

.csx-head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 14px 28px;
	margin: 0 0 22px;
}
.csx-lead { min-width: 0; }

/* 🔴 2026-09-24 第三十三轮：三条线的标题（Protectors / PSA 10 / Sealed Boxes）
   改成**与品牌字标同一套观感** —— 加粗 + 字号略小于字标。用户原话：
     「主页上的 Protectors、PSA10 与 Sealed Box 三处字体，请参照 Logo 字体选择字号并适当加粗，
       字号略小于 Logo，以提升可读性，在手机端也需清晰可见。」

   📐 基准是**实测**的，不是估的：
     · 字标 `cardspicy-wordmark.png`（609×128，CardSpicy，ExtraBold 几何无衬线）
       渲染高 **32px @1280 / 23px @390**（`.cs-wordmark img` 实测 getBoundingClientRect）。
       该图墨迹顶到画布上下边（含 d/S 升部与 p/y 降部 ≈ 0.94em）
       ⇒ 折算**字号等效 ≈ 34px 桌面 / ≈ 24.5px 手机**。
     · 旧值 font-weight **500** 是这三点里最刺眼的一处：字标是 ExtraBold，
       同页的标题却只有 Medium ⇒ 不是「大小」问题，是**轻重不搭**。
   ⇒ 桌面 32px / 800（< 34px ✓ 略小于字标）；手机 23px / 800（< 24.5px ✓，且比旧的 24px/500 更清楚）。
   ⚠️ 字体族**不动**：全站就是 Manrope（字标也是这一族），只用 inherit，别写死别的字体。 */
.csx-title {
	margin: 0;
	font-size: 32px;
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -.022em;
	color: var(--csx-ink);
}
.csx-title a {
	color: inherit;
	text-decoration: none;
	transition: color .18s ease;
}
.csx-title a:hover { color: var(--csx-accent); }

.csx-note {
	margin: 7px 0 0;
	max-width: 54ch;
	font-size: 13px;
	line-height: 1.45;
	color: var(--csx-muted);
}

/* ------------------------------------------------------------ 切换按钮
   🔴 2026-09-22 统一尺寸：桌面所有按钮**等宽**（--csx-chip-w），文字居中。
      改前按钮宽度随标签长短变化（49–142px，差 2.9 倍），三行按钮看起来零散。
      ≤620px 改回内容定宽 —— 原因见下面的响应式注释。

   🔴 2026-10-10（R258e · 用户口径）**按页面层级区分，两处一套语言、强度分级**：
      用户原话：「……在二级菜单页面里，选中态可以像首页那样支持明显的选择效果；而在首页上，
                因为首页整体元素已经比较突出，选中态需要比首页常规样式再淡一点、尺寸也更小
                一些，以形成区分。同时请把两处的选中态形式统一。」
      · 首页（本文件）＝橱窗，且元素密（hero + 三块展示区 + 商品板）⇒ 尺寸**再小一档**、
        选中态**调淡**（只到「看得出来」为止）。
      · 二级菜单页面（`cs-shop-by-ip.php` 的 `.cs-sbi__a`）＝工作区（正在按 IP 筛）⇒
        同尺寸、选中走**明显**档（实心主色 + 白字）。
      · 实测改动：高 34→30、字 13→12.5、等宽 148→132（三行仍等宽 ⇒ 右缘照样对齐）。
      · 旧值逐字留在下面，回滚只需把三处数字换回。 */
.csx-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-left: auto;
}
.csx-chip {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 30px;
	width: var(--csx-chip-w);
	padding: 0 13px;
	border: 1px solid var(--csx-hair);
	border-radius: 999px;
	background: transparent;
	color: var(--csx-ink2);
	font-size: 12.5px;
	font-weight: 500;
	line-height: 1;
	white-space: nowrap;
	text-decoration: none;
	transition: border-color .18s ease, color .18s ease, background-color .18s ease;
}
.csx-chip:hover {
	border-color: var(--csx-hair-strong);
	color: var(--csx-ink);
	background: rgba(0, 0, 0, .03);
}
/* 🔴 2026-10-10（R258e）选中态由**实心**改**淡**。
   旧值（回滚用）：border-color: var(--csx-accent); background: var(--csx-accent); color: #fff;
   理由：首页三条线只是橱窗、不承担「筛选中」的提示职责 ⇒ 选中只需「看得出来」，
   不必每条线都跳一个实心红按钮。二级菜单页面则相反，那边保留实心档。 */
.csx-chip.is-on {
	border-color: rgba(139, 26, 26, .32);
	background: rgba(139, 26, 26, .07);
	color: #8B1A1A;
}
.csx-chip:focus-visible {
	outline: 2px solid var(--csx-accent);
	outline-offset: 2px;
}

/* ------------------------------------------------- R266（1.5.0）· 第二行：IP 胶囊
   两行（分类 / IP）在 `.csx-chiprows` 里**竖向堆叠、右对齐**：
     · 外层 `margin-left:auto` 把整块推到标题右侧（沿用 `.csx-chips` 的老做法）；
     · 两行都保持 `--csx-chip-w` 等宽 ⇒ **右缘继续对齐**（三条线的老口径不变）。
   🔴 整行「在不在」由 PHP 给初值、之后由 showcase.js 按 `data-t` 实时改
      （当前分类下可用 IP < 2 ⇒ 该行 `hidden`）⇒ 这里不给它任何默认显隐。 */
.csx-chiprows {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 7px;
	margin-left: auto;
	min-width: 0;
}
.csx-chiprows .csx-chips { margin-left: 0; }

/* ------------------------------------------------- R266（1.6.0）· 第三级收小一档
   🔴 用户口径：「为了区分跟上面那个菜单的不一致的地方，你得把第三级的这个框做小一点。
                  保持美观。」⇒ 两行虽然共用「胶囊语言」，但**必须一眼看出层级**：
      第 2 级 = 分类行（主，`.csx-chips--cat`，高 30 / 字 12.5 / 等宽 132）
      第 3 级 = IP 行（次，`.csx-chips--ip`，高 26 / 字 11.5 / **宽度自适应**）
   🔴 **宽度为什么不再等宽**：IP 名短（`Pokémon` / `One Piece`），硬撑 132px 会留
      一大片空白、反而显得虚。右缘对齐改由容器 `.csx-chiprows{align-items:flex-end}`
      保证 —— 整行右对齐 ⇒ 右缘照旧齐（三条线的老口径不破）。
   ⚠️ 选择器是两个类（`.csx-chips--ip .csx-chip`）⇒ 特异性高于下面 @media 里的
      单个 `.csx-chip`，无需靠书写顺序取胜；但手机档仍单独再收一档（见 @media）。
   ⚠️ 行内间距那条同理写成 `.csx-chiprows .csx-chips--ip`（0,2,0）——
      基类 `.csx-chips{gap:8px}` 是单类（0,1,0），若只写 `.csx-chips--ip{gap:6px}`
      就变成「同特异性、靠谁在后面」⇒ 一旦 @media 或文件顺序变动会静默失效。 */
.csx-chiprows .csx-chips--ip {
	gap: 6px;
}
.csx-chips--ip .csx-chip {
	height: 26px;
	width: auto;
	padding: 0 10px;
	font-size: 11.5px;
}

/* ---------------------------------------------------------- 产品板那一行
   🔴 2026-09-22（用户长期规则）：「主页每个类目**每行 6 个**、最多两行、
      只有一行零头时就只出一行、最起码出一行」。
      改前是 flex + 固定板宽（`flex:0 0 var(--csx-tile)`）⇒ **每行几个随视口漂移**
      （1320px 容器下能塞 7 个），所以「两行」永远凑不齐。
      现在改成**显式栅格**：每行几个是被写死的常量，不再受容器宽度影响。
      ⚠️ 显隐条数由 showcase.js 的 limitFor() 按同一口径算；
         JS 直接数 `gridTemplateColumns` 的列数，所以**改这里就等于改 JS 的每行数**，
         两边不需要同步维护第二个常量。
      ⚠️ 断点：≥901px 出 6 列；621–900px 出 4 列；≤620px 出 2 列。
   🔴 1.3.0：`align-items` 从 `start` 改成 **`stretch`**（栅格默认值）。
      为什么必须改：加了 Buy 之后，同一行里各板的「内容总高」可能不同 ——
      · 名称 1 行 vs 2 行（已用下面的 min-height 拉平，见「名称框钉成两行高」）
      · **特价板的价格是 2 行**（`<del>` 原价 + `<ins>` 现价叠一行；实测 53 个价格里 3 个）
      两者都会把该板的 Buy 往下推，一行按钮就成锯齿。
      改成 stretch 后每块板都撑到该行最高板的同高，配合
      `.csx-tile > .cs-buy-wrap { margin: auto 0 0 }` 把 Buy **钉到板底**
      ⇒ 无论名称几行、价格几行，一行里的 Buy 永远在同一条基线上。 */
.csx-row {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: var(--csx-gap);
	align-items: stretch;
}

/* 🔴 1.3.0：`.csx-tile` 从 `<a>` 退化成**纯容器 div**。
   原因见 cs-showcase.php 头部 1.3.0 ②：块级 Buy 本身就是 `<a>`，
   而 HTML 不允许 `<a>` 嵌套 `<a>`（浏览器会自动闭合外层、DOM 被拆散）。
   它现在只干两件事：① 当栅格项（承接 showcase.js 的 `hidden` / `data-c`）
   ② 提供 hover 抬升。原来属于它的「整块可点区域」下移到内层 `.csx-link`。
   ⚠️ `data-c` 必须留在这一层（showcase.js:58 取板、:104 取分类是同一个元素）。
   ⚠️ 这里的 `gap` 现在管的是**「价格 ↔ Buy」这一段**（`.csx-link` 内部
      自己另有一套 gap:8px 管「外框/名称/价格」）。取 14px 而不是 8px，是因为
      角标 `.cs-buy__note` 是**压在按钮上角**的（`top:-8px`）—— 间距 8px 时
      角标的顶边会正好顶到价格文字上，挤成一片。 */
.csx-tile {
	display: flex;
	flex-direction: column;
	gap: 14px;
	min-width: 0;
	transition: transform .32s var(--csx-ease);
}
.csx-tile[hidden] { display: none !important; }
.csx-tile:hover { transform: translateY(-5px); }

/* 内层链接：把原来 `.csx-tile` 的排版属性原样搬过来 ——
   「外框 + 名称 + 价格」这一坨的视觉与改前**逐像素一致**，
   只是可点区域不再是整块 tile（Buy 是它的兄弟，点 Buy 不会误跳转）。 */
.csx-link {
	display: flex;
	flex-direction: column;
	gap: 8px;
	min-width: 0;
	text-decoration: none;
	color: inherit;
}
.csx-link:focus-visible {
	outline: 2px solid var(--csx-accent);
	outline-offset: 3px;
	border-radius: var(--csx-radius);
}

/* ---------------------------------------------------------------- 外框
   🔴 三种内容共用这一个框：外框 = 内边距 + 3:4 画板。
      改这一处，三条线的板会同时同比例变化 —— 这是「尺寸统一」的唯一来源。 */
.csx-frame {
	position: relative;
	padding: 12px;
	background: var(--csx-surface);
	border-radius: var(--csx-radius);
	overflow: hidden;
	transition: background-color .32s ease;
}
.csx-tile:hover .csx-frame { background: var(--csx-surface-hover); }

.csx-art {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 3 / 4;
}
.csx-art > svg,
.csx-art > img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
}

/* 真实商品照片：站上的 woocommerce_thumbnail 本身就是 600×800（3:4），
   contain 进去正好铺满画板，不会裁到 slab 的白边。
   .is-loading 由 JS 加在「尚未加载完」的懒图上 —— 切到某个类目时那些图
   才第一次下载，不处理会「啪」地跳出来。 */
.csx-art--photo > img {
	object-fit: contain;
	transition: opacity .3s ease, transform .5s ease;
}
.csx-art--photo > img.is-loading { opacity: 0; }

/* 矢量产品板：每块板自带贴合自身外接矩形的 viewBox（见 cs_board_svg_open），
   所以这里**不能再加缩放** —— 一加就会撞到画板边缘被裁。 */
.csx-art--board > svg { display: block; }

.csx-tile:hover .csx-art--photo > img { transform: scale(1.04); }

/* ------------------------------------------------------------ 名称与价格
   极简优先：名称最多两行，价格一行灰字。完整名称在 title 属性里。 */
.csx-label {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 12.5px;
	line-height: 1.35;
	letter-spacing: -.005em;
	color: var(--csx-ink2);
}
.csx-price {
	font-size: 12.5px;
	line-height: 1.3;
	color: var(--csx-muted);
}
.csx-price del {
	color: #b4b2a9;
	font-size: 11.5px;
	font-weight: 400;
}
.csx-price ins { text-decoration: none; }

/* --------------------------------------------------- 1.3.0：名称框钉成两行高
   🔴 为什么必须要这一步（而不是「看着差不多就行」）：
      加了 Buy 之后，同一行里的「价格 → Buy」必须**高低一致**，否则一行按钮像锯齿。
      而 PSA 10 线的名称长度 21–52 字符（实测），在 6 列（板宽约 197px、
      字号 12.5px）下有的排 1 行、有的排 2 行 ⇒ 价格与 Buy 必然错位。
      钉成两行后三行板的「价格 + Buy」基线完全对齐。
   · 护具线名称 78–84 字符，本来就被 line-clamp 压满 2 行 ⇒ 在这里是 no-op。
   · 封箱线（`'price' => ''`）**不命中** `:has(.csx-price)` ⇒
     那种既没价格也没 Buy 的板不会被无谓撑高（否则只会多出一行空白）。
   · `:has()` 不支持时退化成自然高度 = 改前的表现，不会坏。 */
.csx-tile:has(.csx-price) .csx-label { min-height: calc(2 * 1.35em); }

/* ---------------------------------------------------- 1.3.0：迷你 Buy（尺寸略小）
   🔴 只做「收小」，**不改任何语义**：
      配色 / 边框 / 圆角语言 / 交互态（hover · active · is-busy · is-added）
      全部沿用 cs-cart-ux.php 的 `.cs-buy` 基础样式 ⇒ 以后站内 Buy 换主色，
      这里自动跟着变，不需要回来改第二处。
   🔴 特异性已足够：`.csx-tile .cs-buy` = (0,2,0)，高过 `.cs-buy` (0,1,0)
      以及 cs-cart-ux 里那条 `@media(max-width:600px){.cs-buy{…}}` 的 (0,1,0)……
      注意：媒体查询**不增加特异性**，所以 ≤600px 时本文件的 (0,2,0) 依然赢 ——
      手机端若要再收一档，必须在下面 ≤620px 的块里**再写一条同级规则**，
      不能指望响应式顺序（本文件比 cs-cart-ux 的 `<style>` 早输出，
      但顺序在这里不影响结果，胜负只看特异性）。
   基准（cs-cart-ux）：min-width 132px / padding 11px 22px / 14px / 圆角 9px。 */
.csx-tile > .cs-buy-wrap {
	align-self: center;
	/* `margin: auto 0 0` —— 顶部 auto 把 Buy 顶到板底（配合 .csx-row 的 stretch，
	   见上面的对齐注释）；同时清掉基础样式自带的 `margin-bottom:1rem`，
	   否则每块板下面会多留 16px 空档。 */
	margin: auto 0 0;
	gap: 6px;
}
.csx-tile .cs-buy {
	min-width: 104px;
	padding: 8px 16px;
	border-radius: 8px;
	font-size: 12.5px;
	gap: 5px;
}
/* 角标「In stock / Pre-Order」按比例缩 —— 10px 在 12.5px 的字旁边会压过主文案 */
.csx-tile .cs-buy__note {
	top: -8px;
	right: -5px;
	font-size: 8.5px;
	padding: 1px 5px;
}
.csx-tile .cs-buy__toast { font-size: 11px; line-height: 1.4; }

/* -------------------------------------------------------------- 计数一行 */
.csx-count {
	margin-top: 16px;
	min-height: 0;
	text-align: center;
	font-size: 12px;
	color: var(--csx-muted);
}
.csx-count:empty { display: none; }

/* ------------------------------------------------------------------ 响应式
   🔴 2026-09-22 起「每行几个」= 栅格列数（见上），不再是 --csx-tile 的板宽。
      ⇒ 原来那几档 `--csx-tile: 158/150/134px` 全部删掉，改成改列数；
        板宽现在由「列数 + gap」自动算出，板永远是等宽的（这正是用户要的「每行布局一致」）。*/
@media (max-width: 1080px) {
	.csx-wrap { --csx-gap: 16px; }
	.csx-title { font-size: 29px; }
}
@media (max-width: 900px) {
	.csx-row { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.csx-wrap { --csx-gap: 14px; }
	.csx-block { padding-top: 52px; }
	.csx-title { font-size: 26px; }
	.csx-head { margin-bottom: 18px; }
	.csx-chip { height: 29px; padding: 0 12px; font-size: 12px; }   /* 🔴 R258e：原 32/14/12.5 同步收一档 */
	/* 1.6.0：第三级（IP 行）在平板档再收一档 —— 与分类行的差距照旧「一档」。 */
	.csx-chips--ip .csx-chip { height: 25px; padding: 0 9px; font-size: 11px; }
}

/* 手机：两列产品板。
   🔴 2026-09-22 改：切换条从「一条可横滑的长条」改成**自动换行**（用户要求折两行、不要横滑）。
      为什么手机上不能用等宽 —— 容器内宽 343px：
        · 3 枚/行 ⇒ 每枚 109px，文字只有 81px 可用，而「Storage & Binders」需要 105px
          ⇒ 要么裁字，要么把字号压到 9.7px（低于可读下限）
        · 2 枚/行 ⇒ 每枚 168px，5 枚按钮要 **3 行**
      所以手机上只统一「高度 / 内边距 / 字号」，宽度随文字。
      实测 5 枚恰好折成 2 行（All·Protectors·Grading ／ Storage & Binders·Accessories），
      一个字不裁。等宽带来的整齐感由桌面端负责。
      ⚠️ 改前是 nowrap + overflow-x:auto，护具线按钮条 508px > 375px 视口，
         第 5 枚「Accessories」被挤出屏幕外。 */
@media (max-width: 620px) {
	.csx-wrap {
		--csx-gap: 12px;
		--csx-radius: 12px;
		--csx-chip-w: auto;
		padding: 4px 16px 56px;
	}
	.csx-head { display: block; }
	/* 手机：23px / 800 —— 略小于字标（≈24.5px 等效），比旧的 24px/500 明显更清楚 */
	.csx-title { font-size: 23px; }
	.csx-chips {
		flex-wrap: wrap;
		margin: 14px 0 0;
	}
	/* R266：手机上标题与按钮改上下排 ⇒ 两行按钮块**左对齐铺满**，
	   上外边距只留一份（原来在 `.csx-chips` 上），行间距收到 6px。 */
	.csx-chiprows {
		align-items: flex-start;
		gap: 6px;
		margin: 14px 0 0;
	}
	.csx-chiprows .csx-chips { margin: 0; }
	.csx-chip { flex: 0 0 auto; }
	/* 1.6.0：第三级（IP 行）手机档 —— 最小的那一档（高 23 / 字 11），
	   分类行仍是 29/12 ⇒ 层级差距在手机上同样成立。 */
	.csx-chips--ip .csx-chip { height: 23px; padding: 0 9px; font-size: 11px; }
	.csx-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.csx-frame { padding: 8px; }
	.csx-tile:hover { transform: none; }
	/* 1.3.0 迷你 Buy 的手机档：板更窄（2 列，约 165px），再收一档；
	   角标保留（In stock / Pre-Order 是这个站的关键信息，不能因为小就删），
	   但把字号压到与 11.5px 主文案匹配的比例。 */
	.csx-tile .cs-buy { min-width: 88px; padding: 7px 12px; font-size: 11.5px; }
	.csx-tile .cs-buy__note { font-size: 8px; padding: 1px 4px; top: -7px; right: -4px; }
}

/* 用户要求减弱动效时：不动 */
@media (prefers-reduced-motion: reduce) {
	.csx-wrap *,
	.csx-wrap *::before,
	.csx-wrap *::after {
		transition-duration: .01ms !important;
		animation-duration: .01ms !important;
	}
	.csx-tile:hover { transform: none; }
	.csx-tile:hover .csx-art--photo > img { transform: none; }
}
