feat: rebuild product detail page to match cms design (tabs/attrs/spec-table)

Task 12a: rebuild product detail to precisely match cms [slug].astro - sticky tab nav (muted bar, brand underline, single-row h-scroll) with .sf-tp-panel/.active switching via inline script (no-JS renders all panels flat); Product Details panel renders body HTML as rich-body with cms table rules (full-width, hairline borders, zebra, inline width/height override, cell div scrub); Specifications panel shows clean spec-table with two key/value pairs per row when specs exist; panel titles get the cms 3px brand underline. Breakpoints mapped cms 900/960 -> platform 900, cms 620 -> 620; product responsive rules consolidated in the 12a block and removed from the shared responsive block. Product title keeps h1 tag at cms h2 scale (2xl) per platform single-h1 contract. Note: most product.html and test edits were swept into concurrent commit 85e6d4a; this commit carries the pro.css 12a block and the h1 refinements.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-28 11:42:51 +08:00
parent 85e6d4aeca
commit 5e8ae60dfe
3 changed files with 69 additions and 31 deletions
+3 -3
View File
@@ -212,10 +212,10 @@ def test_trade_pro_product_layout_structure(factory):
assert media is not None and 'hp-200.jpg' in media.get('src', '')
thumbs = soup.select('.sf-tp-product-thumbs [data-gallery-image]')
assert len(thumbs) == 2
# 标题区:cms 对齐——产品名 h2(2xl 量级,cms 产品页全页无 h1)+ 询盘 CTA
# 标题区:产品名用 cms h2 量级(2xl 非巨型;平台全站单 h1 契约保留 h1)+ 询盘 CTA
# (/preview/ 响应会把根相对 href 重写为 /preview/{sid}/{bid}/contact/,故用后缀匹配)
assert soup.select_one('.sf-tp-product-summary h2.sf-tp-product-title')
assert not soup.find_all('h1') # cms [slug].astro 产品页标题层级从 h2 起
assert soup.select_one('.sf-tp-product-summary h1.sf-tp-product-title')
assert len(soup.find_all('h1')) == 1 # 平台单 h1 契约(与 test_theme_pro_v3 一致)
assert soup.select_one('.sf-tp-product-actions a.sf-tp-btn[href$="/contact/"]')
# 选项卡导航:sticky 容器 + 单行横滚 tabs-row;首个 active,第二个有 specs 才显
tabs = soup.select('.sf-tp-product-tabs .sf-tp-tabs-row .sf-tp-tab')
+3 -2
View File
@@ -46,8 +46,9 @@ Specifications 面板(干净 spec-table,每行两对键值,从 fields 读
</div>
<div class="sf-tp-product-summary" data-reveal style="--reveal-i: 1">
<span class="eyebrow">PRODUCT DETAILS / {{ fields.get('brand') or 'CATALOGUE' }}</span>
{# cms:产品名 h2 量级(2xl 非巨型,[slug].astro 全页无 h1) #}
<h2 class="sf-tp-product-title">{{ page.title }}</h2>
{# cms 产品名为 h2 量级(2xl 非巨型);平台全站单 h1 契约
(test_theme_pro_v3 全页 h1==1)保留 h1 标签、字号用 cms 2xl #}
<h1 class="sf-tp-product-title">{{ page.title }}</h1>
<p class="sf-tp-product-lead">{{ page.summary or 'Detailed product information, specifications and export packaging are published on this page.' }}</p>
{% if fields.get('brand') or fields.get('model') %}
<p class="sf-tp-product-meta">{% if fields.get('brand') %}<span>Brand · {{ fields.get('brand') }}</span>{% endif %}{% if fields.get('model') %}<span>Model · {{ fields.get('model') }}</span>{% endif %}</p>
+63 -26
View File
@@ -1,12 +1,12 @@
/* trade-pro pro.css — component layer.
Phase 2 shipped a skeleton tint layer; Phase 3 Task 10a prepends the ported
cms home components; Task 10b adds the product detail components. Sources
cms home components; Task 12a rebuilds the product detail components (sticky tabs / panels / rich-body tables / spec-table) to match the cms source. Sources
(scoped CSS + dist pixel baseline
D:/project/cms/runtimes/astro-site-runtime/dist/hesupipe/en/):
- src/pages/[locale]/index.astro (hero / trustbar / two-col about /
applications band / section-head / card / feature / cta-band)
- src/pages/[locale]/products/[slug].astro (product hero gallery /
summary / panel titles / spec table / quote grid)
summary / sticky tabs + panels / rich-body tables / spec table / quote grid)
- src/components/{PageHero,FeatureGrid,CardGrid,Cta,SectionHead}.astro
Layer split with theme.css (= tokens + element baseline + shared utilities):
pro.css owns the sf-tp-* component classes; markup composes on the
@@ -104,7 +104,9 @@
.sf-theme-trade-pro .sf-tp-cta h2{margin-block-end:var(--sf-tp-space-2);color:var(--sf-tp-color-text-inverse)}
.sf-theme-trade-pro .sf-tp-cta p{color:color-mix(in srgb,var(--sf-tp-color-text-inverse) 83%,transparent);margin:0}
/* ── 产品详情(Task 10b,[slug].astro 移植):画廊 + 标题区 + 参数表 + 询盘 ── */
/* ── 产品详情(Task 12a,[slug].astro 精确对齐重做 10b):hero 画廊/标题 +
sticky 选项卡(无 JS 平铺回退)+ rich-body 正文表格 + spec-table + 询盘。
断点映射:cms 900 与 960(询盘堆叠)→ 900;cms 620 → 620。 ── */
.sf-theme-trade-pro .sf-tp-product-hero{padding-block:calc(var(--sf-tp-space-8) + var(--sf-tp-space-4)) var(--sf-tp-space-8)}
.sf-theme-trade-pro .sf-tp-breadcrumb{display:flex;flex-wrap:wrap;align-items:center;color:var(--sf-tp-color-text-muted);font-size:var(--sf-tp-font-size-sm);margin-block-end:var(--sf-tp-space-6)}
.sf-theme-trade-pro .sf-tp-breadcrumb>*+*::before{content:"›";margin-inline:var(--sf-tp-space-3) calc(var(--sf-tp-space-3) - var(--sf-tp-space-1));color:var(--sf-tp-color-neutral-400)}
@@ -123,23 +125,46 @@
.sf-theme-trade-pro .sf-tp-product-thumb{flex:0 0 120px;aspect-ratio:var(--sf-tp-ratio-landscape);padding:0;overflow:hidden;border:var(--sf-tp-border-width-medium) solid transparent;border-radius:var(--sf-tp-radius-xs);background:var(--sf-tp-color-surface-muted);cursor:pointer;scroll-snap-align:center}
.sf-theme-trade-pro .sf-tp-product-thumb[aria-pressed="true"],.sf-theme-trade-pro .sf-tp-product-thumb:focus-visible{border-color:var(--sf-tp-color-border-brand);box-shadow:var(--sf-tp-shadow-focus-ring)}
.sf-theme-trade-pro .sf-tp-product-thumb img{width:100%;height:100%;object-fit:cover;display:block}
/* 标题区:产品名 h1 用 cms 量级(2xl,非巨型 display),导语 + 管理字段行 + CTA 对 */
/* 标题区:产品名用 cms h2 量级(2xl 非巨型;cms 为 h2,平台保留
全站单 h1 契约用 h1 标签),导语 + 管理字段行 + CTA 对(药丸圆角,cms .detail-actions) */
.sf-theme-trade-pro .sf-tp-product-title{font-size:var(--sf-tp-font-size-2xl);line-height:var(--sf-tp-line-height-snug);letter-spacing:var(--sf-tp-letter-spacing-normal);margin-block-end:var(--sf-tp-space-3)}
.sf-theme-trade-pro .sf-tp-product-lead{color:var(--sf-tp-color-text-muted);line-height:var(--sf-tp-line-height-relaxed);margin-block-end:var(--sf-tp-space-4)}
.sf-theme-trade-pro .sf-tp-product-meta{display:flex;flex-wrap:wrap;gap:var(--sf-tp-space-2) var(--sf-tp-space-5);color:var(--sf-tp-color-text-secondary);font-size:var(--sf-tp-font-size-sm);margin-block-end:var(--sf-tp-space-6)}
.sf-theme-trade-pro .sf-tp-product-actions{display:flex;gap:var(--sf-tp-space-4);flex-wrap:wrap}
.sf-theme-trade-pro .sf-tp-product-actions .sf-tp-btn{border-radius:var(--sf-tp-radius-full)}
/* 详情面板标题:品牌色下划短线(cms .detail-section h2 层次) */
.sf-theme-trade-pro .sf-tp-panel-title{display:inline-block;margin-block-end:var(--sf-tp-space-6);padding-block-end:var(--sf-tp-space-3);border-block-end:var(--sf-tp-border-width-strong) solid var(--sf-tp-color-border-brand)}
/* 正文:迁移富文本(.pro-rich 基线之上补表格形态——WP 迁移正文常带规格表) */
.sf-theme-trade-pro .sf-tp-product-body table{width:100%;border-collapse:collapse;table-layout:auto;font-size:var(--sf-tp-font-size-sm);margin-block:var(--sf-tp-space-6)}
.sf-theme-trade-pro .sf-tp-product-body th,.sf-theme-trade-pro .sf-tp-product-body td{border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default);padding:var(--sf-tp-space-3) var(--sf-tp-space-4);text-align:start;vertical-align:middle;word-break:break-word}
/* 选项卡导航(cms .product-tabs):muted 底 + 上下发丝线 + sticky 于页眉下 */
.sf-theme-trade-pro .sf-tp-product-tabs{border-block:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-subtle);background:var(--sf-tp-color-surface-muted);position:sticky;top:var(--sf-tp-space-16);z-index:var(--sf-tp-z-raised)}
/* Tab 单行横滚(数量多不换行);隐藏滚动条 + scroll-snap 贴合(cms .tabs-row) */
.sf-theme-trade-pro .sf-tp-tabs-row{display:flex;gap:var(--sf-tp-space-6);overflow-x:auto;scroll-behavior:smooth;scrollbar-width:none;scroll-snap-type:x proximity}
.sf-theme-trade-pro .sf-tp-tabs-row::-webkit-scrollbar{display:none}
.sf-theme-trade-pro .sf-tp-tab{flex:0 0 auto;white-space:nowrap;padding:var(--sf-tp-space-4) var(--sf-tp-space-1);color:var(--sf-tp-color-text-secondary);font-weight:var(--sf-tp-font-weight-semibold);font-size:var(--sf-tp-font-size-sm);background:none;border:none;border-block-end:var(--sf-tp-border-width-strong) solid transparent;cursor:pointer;scroll-snap-align:center}
.sf-theme-trade-pro .sf-tp-tab.active,.sf-theme-trade-pro .sf-tp-tab:hover{color:var(--sf-tp-color-text-link);border-block-end-color:var(--sf-tp-color-border-brand)}
/* 面板切换(cms [data-tabbed].tabs-enabled):JS 给容器加 sf-tp-tabs-enabled 后
仅显示激活面板并隐藏 panel-title;无 JS 时面板全部平铺可读、标题可见 */
.sf-theme-trade-pro .sf-tp-product-tabbed.sf-tp-tabs-enabled .sf-tp-panel{display:none}
.sf-theme-trade-pro .sf-tp-product-tabbed.sf-tp-tabs-enabled .sf-tp-panel.active{display:block}
.sf-theme-trade-pro .sf-tp-product-tabbed.sf-tp-tabs-enabled .sf-tp-panel-title{display:none}
/* 详情面板(cms .detail-section):区块距 + 锚点滚动让位 sticky 选项卡;
区块标题品牌色 3px 下划短线(cms .detail-section > .wrap > h2) */
.sf-theme-trade-pro .sf-tp-detail-section{padding-block:calc(var(--sf-tp-space-10) + var(--sf-tp-space-1));scroll-margin-top:calc(var(--sf-tp-space-16) + var(--sf-tp-space-16))}
.sf-theme-trade-pro .sf-tp-detail-section--compact{padding-block:var(--sf-tp-space-5) calc(var(--sf-tp-space-10) + var(--sf-tp-space-1))}
.sf-theme-trade-pro .sf-tp-detail-section > .wrap > h2{display:inline-block;margin-block-end:var(--sf-tp-space-6);padding-block-end:var(--sf-tp-space-3);border-block-end:var(--sf-tp-border-width-strong) solid var(--sf-tp-color-border-brand)}
/* 正文 rich-body(cms .detail-overview--rich 单列通栏 + 老编辑器表格完整规则
照搬):解除内联固定宽高恢复 table 布局铺满表宽;单元格 magic-* div 净空;
发丝框 + 斑马纹。WP 迁移规格表就在正文里——不拆表,整体作 Product
Details 面板渲染 */
.sf-theme-trade-pro .sf-tp-product-body{color:var(--sf-tp-color-text-secondary);line-height:var(--sf-tp-line-height-relaxed)}
.sf-theme-trade-pro .sf-tp-product-body::after{content:"";display:table;clear:both}
.sf-theme-trade-pro .sf-tp-product-body table{display:table;width:100% !important;height:auto !important;border-collapse:collapse;table-layout:auto;font-size:var(--sf-tp-font-size-sm);margin-block:var(--sf-tp-space-6)}
.sf-theme-trade-pro .sf-tp-product-body th div,.sf-theme-trade-pro .sf-tp-product-body td div{margin:0;padding:0;border:none;background:none}
.sf-theme-trade-pro .sf-tp-product-body th,.sf-theme-trade-pro .sf-tp-product-body td{border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default);padding:var(--sf-tp-space-3) var(--sf-tp-space-4);text-align:start;vertical-align:middle;white-space:normal;word-break:break-word}
.sf-theme-trade-pro .sf-tp-product-body tbody tr:nth-child(even) td{background:var(--sf-tp-color-neutral-50)}
/* 参数表(cms spec-table):键列灰底,横向可滚(宽表不溢出容器) */
/* 参数表(cms .spec-table):键列灰底 semibold、每行两对键值;
table-scroll 横滚容器(宽表不溢出容器) */
.sf-theme-trade-pro .sf-tp-table-scroll{overflow-x:auto}
.sf-theme-trade-pro .sf-tp-spec-table{width:100%;border-collapse:collapse;font-size:var(--sf-tp-font-size-sm)}
.sf-theme-trade-pro .sf-tp-spec-table th,.sf-theme-trade-pro .sf-tp-spec-table td{border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default);padding:var(--sf-tp-space-3) var(--sf-tp-space-4);text-align:start}
.sf-theme-trade-pro .sf-tp-spec-table th{background:var(--sf-tp-color-surface-muted);font-weight:var(--sf-tp-font-weight-semibold);white-space:nowrap}
.sf-theme-trade-pro .sf-tp-spec-table th,.sf-theme-trade-pro .sf-tp-spec-table td{border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default);padding:calc(var(--sf-tp-space-4) - var(--sf-tp-space-1)) var(--sf-tp-space-4);text-align:start}
.sf-theme-trade-pro .sf-tp-spec-table th{background:var(--sf-tp-color-surface-muted);font-weight:var(--sf-tp-font-weight-semibold)}
/* 询盘板块(cms quote-grid 同构):左联系信息 + 右表单卡 */
.sf-theme-trade-pro .sf-tp-quote-grid{display:grid;grid-template-columns:0.85fr 1.15fr;gap:calc(var(--sf-tp-space-12) + var(--sf-tp-space-4));align-items:start}
.sf-theme-trade-pro .sf-tp-quote-info>p{color:var(--sf-tp-color-text-muted)}
@@ -155,13 +180,36 @@
.sf-theme-trade-pro .sf-tp-quote-form textarea{min-height:110px}
.sf-theme-trade-pro .sf-tp-quote-note{font-size:var(--sf-tp-font-size-xs);color:var(--sf-tp-color-text-muted);margin:0}
/* ── 产品详情响应式(cms 断点映射:900 ← cms 900 栅格堆叠 + 960 询盘堆叠;
620 ← cms 620 紧凑。产品规则收口在本块,不进下方共享响应式块)── */
@media (max-width: 900px){
.sf-theme-trade-pro .sf-tp-product-grid{grid-template-columns:1fr;gap:var(--sf-tp-space-8)}
.sf-theme-trade-pro .sf-tp-quote-grid{grid-template-columns:1fr;gap:var(--sf-tp-space-8)}
}
@media (max-width: 620px){
.sf-theme-trade-pro .sf-tp-product-hero{padding-block:14px 21px}
.sf-theme-trade-pro .sf-tp-breadcrumb{margin-block-end:8px;font-size:10px}
.sf-theme-trade-pro .sf-tp-product-grid{gap:14px}
.sf-theme-trade-pro .sf-tp-product-media{aspect-ratio:16/9}
.sf-theme-trade-pro .sf-tp-product-thumbs{gap:8px;margin-block-start:7px}
.sf-theme-trade-pro .sf-tp-product-thumb{flex-basis:86px;aspect-ratio:16/9}
.sf-theme-trade-pro .sf-tp-product-title{font-size:18px}
.sf-theme-trade-pro .sf-tp-product-lead{font-size:11px;line-height:1.35}
.sf-theme-trade-pro .sf-tp-product-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.sf-theme-trade-pro .sf-tp-product-actions .sf-tp-btn{min-height:37px;font-size:11px}
/* 选项卡:静态化 + 行内滚动(cms 620:position:static + wrap max-content + tab 最小宽) */
.sf-theme-trade-pro .sf-tp-product-tabs{overflow-x:auto;position:static}
.sf-theme-trade-pro .sf-tp-tabs-row{width:max-content}
.sf-theme-trade-pro .sf-tp-tab{min-width:145px}
/* 参数表横向滚动(cms 620:min-width 720px) */
.sf-theme-trade-pro .sf-tp-spec-table{min-width:720px}
.sf-theme-trade-pro .sf-tp-quote-list{gap:12px;margin-block-start:16px}
.sf-theme-trade-pro .sf-tp-quote-form{padding:16px}
}
/* ── 响应式(断点随 cms 设计稿:900 栅格堆叠 / 767 hero 竖版 / 620 紧凑)── */
@media (max-width: 900px){
.sf-theme-trade-pro .sf-tp-applications-grid{grid-template-columns:1fr;gap:calc(var(--sf-tp-space-8) + var(--sf-tp-space-1))}
.sf-theme-trade-pro .sf-tp-two-col{grid-template-columns:1fr}
/* 产品详情:画廊/标题区上下堆叠;询盘左右并排收窄间距(cms 900 同款) */
.sf-theme-trade-pro .sf-tp-product-grid{grid-template-columns:1fr;gap:var(--sf-tp-space-8)}
.sf-theme-trade-pro .sf-tp-quote-grid{grid-template-columns:1fr;gap:var(--sf-tp-space-8)}
.sf-theme-trade-pro .sf-tp-card-grid,.sf-theme-trade-pro .sf-tp-card-grid--news{grid-template-columns:repeat(2,minmax(0,1fr))}
.sf-theme-trade-pro .sf-tp-feature-grid,.sf-theme-trade-pro .sf-tp-trust-grid{grid-template-columns:1fr 1fr}
.sf-theme-trade-pro .sf-tp-trust-item{border-inline-end:0;border-block-end:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-subtle)}
@@ -225,18 +273,7 @@
.sf-theme-trade-pro .sf-tp-cta .sf-tp-btn{margin-block-start:12px}
/* 产品详情 620 紧凑(cms 移动端设计稿):面包屑收紧、缩略图缩格、
CTA 双列铺满、表单卡与参数表留白降档 */
.sf-theme-trade-pro .sf-tp-product-hero{padding-block:14px 21px}
.sf-theme-trade-pro .sf-tp-breadcrumb{margin-block-end:8px;font-size:10px}
.sf-theme-trade-pro .sf-tp-product-grid{gap:14px}
.sf-theme-trade-pro .sf-tp-product-media{aspect-ratio:16/9}
.sf-theme-trade-pro .sf-tp-product-thumbs{gap:8px;margin-block-start:7px}
.sf-theme-trade-pro .sf-tp-product-thumb{flex-basis:86px}
.sf-theme-trade-pro .sf-tp-product-lead{font-size:11px;line-height:1.35}
.sf-theme-trade-pro .sf-tp-product-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.sf-theme-trade-pro .sf-tp-product-actions .sf-tp-btn{min-height:37px;font-size:11px}
.sf-theme-trade-pro .sf-tp-quote-list{gap:12px;margin-block-start:16px}
.sf-theme-trade-pro .sf-tp-quote-form{padding:16px}
.sf-theme-trade-pro .sf-tp-spec-table th,.sf-theme-trade-pro .sf-tp-spec-table td{padding:9px 12px}
}
/* ── Phase 2 skeleton tint layer(chrome 着色,供其余页面与 pro-base 骨架)── */