feat: port cms listing layout into trade-pro (kind-branched cards/filters/pagination)
Task 10c. listing.html (category.html now includes it) replaces the thin pro-inner-hero variant with the cms list designs: - product-like listings (product/vehicle/brand/case/service) get the products/[...page].astro form: ported PageHero, 260px sticky category side panel, 3-col sf-tp-card grid reusing the 10a card components - post-like listings (/news/, /post/) get the news/[...page].astro form: 1fr+310px two-col layout, horizontal news rows (290px media + tag/ title/summary/Read more), three aside boxes (Latest/Popular/count) - pagination is the cms Pagination window (first/last + current-2..+2, ellipsis collapse) with arrow-left/arrow-right SVG icons and builder-consistent URLs (page 1 = section root) - platform filter contract kept: .pro-filter-panel stays the immediate previous sibling of .pro-filter-scope (pro.js previousElementSibling lookup); cards/rows carry .pro-card + data-brand/data-category - empty sections hide filters/grid/pagination behind a friendly empty state (noindex scaffold pages) Test: test_trade_pro_listing_layout_structure drives a real build with 105 imported products + 3 posts, asserting both branches, static pagination on /categories/pumps/ pages 1-2, contract adjacency, and no bare arrow glyphs. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +1,4 @@
|
||||
<section class="pro-inner-hero pro-listing-hero"><div class="pro-wrap"><span class="pro-eyebrow">DISCOVER / {{'CATEGORY' if kind=='category' else 'COLLECTION'}}</span><h1>{{page.title}}</h1><p>{{page.summary or 'Browse all published content in this section.'}}</p><div class="pro-breadcrumb"><a href="/">Home</a><span>/</span><strong>{{page.title}}</strong></div></div></section>
|
||||
<section class="pro-section pro-list-section"><div class="pro-wrap">{{ filters() }}<div class="pro-filter-scope">{{grid(listing,'catalog')}}</div>{% if pagination and pagination.pages>1 %}<nav class="pro-pages-nav" aria-label="Catalogue pagination">{% if pagination.previous %}<a href="{{pagination.previous}}" rel="prev">{{ icon('arrow-left') }} Previous</a>{% endif %}<span>Page {{pagination.page}} of {{pagination.pages}}</span>{% if pagination.next %}<a href="{{pagination.next}}" rel="next">Next {{ icon('arrow-right') }}</a>{% endif %}</nav>{% endif %}</div></section>
|
||||
{# 派生分类页与 listing 同构(Task 10c 起共用同一列表布局;
|
||||
分类上下文由 theme_pro.select_listing 按 page.category 过滤产品组,
|
||||
分页来自构建期 render_paginated 的 _pagination)。 #}
|
||||
{% include 'pages/listing.html' %}
|
||||
|
||||
@@ -1,2 +1,131 @@
|
||||
<section class="pro-inner-hero pro-listing-hero"><div class="pro-wrap"><span class="pro-eyebrow">DISCOVER / {{'CATEGORY' if kind=='category' else 'COLLECTION'}}</span><h1>{{page.title}}</h1><p>{{page.summary or 'Browse all published content in this section.'}}</p><div class="pro-breadcrumb"><a href="/">Home</a><span>/</span><strong>{{page.title}}</strong></div></div></section>
|
||||
<section class="pro-section pro-list-section"><div class="pro-wrap">{{ filters() }}<div class="pro-filter-scope">{{grid(listing,'catalog')}}</div>{% if pagination and pagination.pages>1 %}<nav class="pro-pages-nav" aria-label="Catalogue pagination">{% if pagination.previous %}<a href="{{pagination.previous}}" rel="prev">{{ icon('arrow-left') }} Previous</a>{% endif %}<span>Page {{pagination.page}} of {{pagination.pages}}</span>{% if pagination.next %}<a href="{{pagination.next}}" rel="next">Next {{ icon('arrow-right') }}</a>{% endif %}</nav>{% endif %}</div></section>
|
||||
{# trade-pro listing / category — cms 列表设计移植(Task 10c)。
|
||||
设计源 D:/project/cms/runtimes/astro-site-runtime/src/pages/[locale]/:
|
||||
- products/[...page].astro:PageHero + 260px 产品分类侧栏(sticky)+
|
||||
SectionHead + 3 列卡片栅格(CardGrid cols-3)+ 窗口式分页
|
||||
- news/[...page].astro:PageHero + 1fr/310px 双栏;列表列为横向新闻行
|
||||
(290px 封面 + tag/标题/摘要/Read more),侧栏三盒
|
||||
(Latest / Popular / Categories 计数)
|
||||
与 cms 的结构决策:
|
||||
1. kind 分支按列表内容类型:post 类(/news/、/post/ 等文章集合)用
|
||||
新闻行形态;其余(product/vehicle/brand/case/service)复用产品卡片
|
||||
栅格——cms 只定义了这两种列表设计,品牌/案例/服务映射到产品卡形态
|
||||
(与 brand.html 相关产品、product.html 相关产品一致)。
|
||||
2. 产品分类侧栏仅产品类列表渲染(侧栏链接是产品分类语义,出现在
|
||||
/brands/ 等页面会误导);文章分支的侧栏是 cms 新闻三盒。空分类
|
||||
数据时侧栏整段隐藏,主列变单栏。
|
||||
3. cms news 页的 Tab 行(All/Company News/...)与 products 页 hero 的
|
||||
“Explore Products”锚点按钮是内容数据驱动 / 页内锚点跳转,平台无
|
||||
对应数据源与目标锚点,不移植;筛选面板承担列表交互入口。
|
||||
4. 平台筛选契约(test_theme_pro_v3 对所有主题 listing 断言)保留:
|
||||
filters() 宏输出 .pro-filter-panel 且必须保持为 .pro-filter-scope
|
||||
的紧邻前兄弟(pro.js 用 previousElementSibling 定位面板);卡片与
|
||||
新闻行都携带 .pro-card + data-brand/data-category(pro.js 过滤的
|
||||
数据源与零结果空态都依赖它们)。
|
||||
5. 分页器是 cms Pagination 的窗口式页码(首尾必现 + 当前±2,其余折叠
|
||||
为省略号),上一页/下一页用 arrow-left/arrow-right SVG(Task 9 图标
|
||||
契约:交互箭头一律 SVG,无裸箭头字符);页码 URL 与构建期静态分页
|
||||
路由一致(第 1 页 = 栏目根,形如 /products/page/2/ 递增)。
|
||||
6. 空列表:筛选、栅格、分页整段隐藏,替换为友好空态提示(cms 站点
|
||||
恒有内容,平台必须处理 noindex 栏目占位页的空集)。 #}
|
||||
{% set tp_post_like = (listing and listing[0].type == 'post') or ('news' in route or 'post' in route) %}
|
||||
{% set tp_eyebrow = 'NEWS & INSIGHTS' if tp_post_like else 'PRODUCT CATALOGUE' %}
|
||||
{% set tp_hero_img = safe_image(page.cover) %}
|
||||
{% set tp_lead = page.summary or ('Industry updates, project stories and exhibition news from our team.' if tp_post_like else 'Browse the full catalogue with specifications, brands and categories.') %}
|
||||
{% set pg_root = (route.split('/page/')[0]).rstrip('/') ~ '/' %}
|
||||
{# 分页导航宏:显式传参(pg/base/icon),不依赖模板上下文闭包 #}
|
||||
{% macro tp_pages(pg, base, icon) -%}
|
||||
{% if pg and pg.pages > 1 %}
|
||||
{% set cur = pg.page %}{% set last = pg.pages %}{% set win = [] %}
|
||||
{% for i in range(1, last + 1) %}
|
||||
{% if i == 1 or i == last or (i - cur)|abs <= 2 %}{% if win.append(i) %}{% endif %}
|
||||
{% elif win and win[-1] != '…' %}{% if win.append('…') %}{% endif %}{% endif %}
|
||||
{% endfor %}
|
||||
<nav class="sf-tp-pagination" aria-label="Pagination">
|
||||
{% if pg.previous %}<a class="sf-tp-page-arrow" href="{{ pg.previous }}" rel="prev" aria-label="Previous page">{{ icon('arrow-left', size='16') }}</a>
|
||||
{% else %}<span class="sf-tp-page-arrow is-disabled" aria-hidden="true">{{ icon('arrow-left', size='16') }}</span>{% endif %}
|
||||
{% for n in win %}{% if n == '…' %}<span class="sf-tp-page-dots">…</span>
|
||||
{% elif n == cur %}<span class="sf-tp-page-num is-active" aria-current="page">{{ n }}</span>
|
||||
{% else %}<a class="sf-tp-page-num" href="{{ base if n == 1 else base ~ 'page/' ~ n ~ '/' }}">{{ n }}</a>{% endif %}{% endfor %}
|
||||
{% if pg.next %}<a class="sf-tp-page-arrow" href="{{ pg.next }}" rel="next" aria-label="Next page">{{ icon('arrow-right', size='16') }}</a>
|
||||
{% else %}<span class="sf-tp-page-arrow is-disabled" aria-hidden="true">{{ icon('arrow-right', size='16') }}</span>{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
<section class="sf-tp-page-hero">
|
||||
{% if tp_hero_img %}<img class="sf-tp-page-hero-bg" src="{{ tp_hero_img }}" alt="" width="1600" height="900" fetchpriority="high" decoding="async">{% endif %}
|
||||
<div class="sf-tp-page-hero-overlay" aria-hidden="true"></div>
|
||||
<div class="wrap">
|
||||
<div class="sf-tp-page-hero-copy" data-reveal>
|
||||
<span class="eyebrow">{{ tp_eyebrow }}</span>
|
||||
<h1>{{ page.title }}</h1>
|
||||
<p class="sf-tp-page-hero-lead">{{ tp_lead }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% if listing %}
|
||||
{% if tp_post_like %}
|
||||
<section class="section sf-tp-news-section"><div class="wrap"><div class="sf-tp-news-layout">
|
||||
<div class="sf-tp-news-list">
|
||||
{{ filters() }}
|
||||
<div class="pro-filter-scope sf-tp-news-rows">
|
||||
{% for item in listing %}
|
||||
<article class="sf-tp-news-row pro-card" data-reveal style="--reveal-i: {{ loop.index0 % 3 }}" data-brand="{{ fields_of(item).get('brand','') }}" data-category="{{ fields_of(item).get('category','') }}">
|
||||
<div class="sf-tp-news-row-media sf-tp-card-media">{{ cover(item, 'post') }}</div>
|
||||
<div class="sf-tp-news-body">
|
||||
<span class="sf-tp-tag">{{ fields_of(item).get('tag') or fields_of(item).get('category') or 'News' }}</span>
|
||||
<h3><a href="{{ safe_href(item.route) }}">{{ item.title }}</a></h3>
|
||||
<p>{{ (item.summary or '')[:200] }}</p>
|
||||
<a class="sf-tp-more" href="{{ safe_href(item.route) }}">Read more {{ icon('arrow-right', cls='sf-tp-icon--sm') }}</a>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ tp_pages(pagination, pg_root, icon) }}
|
||||
</div>
|
||||
<aside class="sf-tp-news-aside">
|
||||
<div class="sf-tp-aside-box" data-reveal><h3>Latest posts</h3>{% for p in listing[:5] %}<p><a href="{{ safe_href(p.route) }}">{{ p.title }}</a></p>{% endfor %}</div>
|
||||
<div class="sf-tp-aside-box" data-reveal style="--reveal-i: 1"><h3>Popular reads</h3><ol>{% for p in listing[:5] %}<li>{{ p.title }}</li>{% endfor %}</ol></div>
|
||||
<div class="sf-tp-aside-box" data-reveal style="--reveal-i: 2"><h3>Categories</h3><p>All news <strong>{{ groups['post']|length }}</strong></p></div>
|
||||
</aside>
|
||||
</div></div></section>
|
||||
{% else %}
|
||||
{% set tp_kind = listing[0].type %}
|
||||
{% set tp_show_side = categories and tp_kind in ('product', 'vehicle') %}
|
||||
<section class="section sf-tp-catalogue-section"><div class="wrap{{ ' sf-tp-catalogue-layout' if tp_show_side else ' sf-tp-catalogue-single' }}">
|
||||
{% if tp_show_side %}
|
||||
<aside class="sf-tp-side-panel" aria-label="Product categories" data-reveal>
|
||||
<h3>Product categories</h3>
|
||||
<a class="sf-tp-side-link{{ ' sf-tp-side-link--active' if route == '/products/' }}" href="/products/">All products</a>
|
||||
{% for cat in categories[:12] %}<a class="sf-tp-side-link{{ ' sf-tp-side-link--active' if cat.url == route }}" href="{{ cat.url }}">{{ cat.name }}</a>{% endfor %}
|
||||
</aside>
|
||||
{% endif %}
|
||||
<div class="sf-tp-catalogue-main">
|
||||
<div class="sf-tp-section-head" data-reveal>
|
||||
<div><span class="eyebrow">{{ tp_eyebrow }}</span><h2>{{ page.title }}</h2></div>
|
||||
<p class="sf-tp-intro">{{ tp_lead }}</p>
|
||||
</div>
|
||||
{{ filters() }}
|
||||
<div class="pro-filter-scope sf-tp-card-grid sf-tp-card-grid--listing">
|
||||
{% for item in listing %}
|
||||
<a class="sf-tp-card pro-card" href="{{ safe_href(item.route) }}" data-reveal style="--reveal-i: {{ loop.index0 % 4 }}" data-brand="{{ fields_of(item).get('brand','') }}" data-category="{{ fields_of(item).get('category','') }}">
|
||||
<div class="sf-tp-card-media">{{ cover(item, tp_kind) }}</div>
|
||||
<div class="sf-tp-card-body">
|
||||
<h3>{{ item.title }}</h3>
|
||||
<p>{{ (item.summary or 'Published specifications available on request.').split('.')[0] }}.</p>
|
||||
<span class="sf-tp-more">View details {{ icon('arrow-right', cls='sf-tp-icon--sm') }}</span>
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ tp_pages(pagination, pg_root, icon) }}
|
||||
</div>
|
||||
</div></section>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<section class="section sf-tp-listing-section"><div class="wrap">
|
||||
<div class="sf-tp-listing-empty" data-reveal>
|
||||
<h2>Nothing published here yet</h2>
|
||||
<p>Content added to this section in the admin console appears here automatically.</p>
|
||||
</div>
|
||||
</div></section>
|
||||
{% endif %}
|
||||
|
||||
@@ -273,3 +273,91 @@
|
||||
|
||||
/* 询盘蜜罐:隐藏但不移出 DOM(pro-base 的 .pro-inquiry 作用域规则不覆盖新表单容器) */
|
||||
.sf-theme-trade-pro .pro-honeypot{position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}
|
||||
|
||||
/* ── Task 10c:listing 列表页(products/news 列表移植)──
|
||||
源 src/pages/[locale]/products/[...page].astro(PageHero / 260px 分类
|
||||
侧栏 / CardGrid cols-3 / Pagination)与 news/[...page].astro
|
||||
(1fr+310px 双栏 / news-row 横向行 / aside-box 侧栏盒)。 */
|
||||
|
||||
/* 内页 PageHero:浅品牌横幅;有封面时叠图 + brand-soft 渐变罩(无图纯渐变) */
|
||||
.sf-theme-trade-pro .sf-tp-page-hero{position:relative;display:flex;align-items:center;overflow:hidden;min-height:calc(var(--sf-tp-space-24) * 3.5);padding-block:var(--sf-tp-space-12) calc(var(--sf-tp-space-10) + var(--sf-tp-space-1));background:linear-gradient(115deg,var(--sf-tp-color-surface-brand-soft),color-mix(in srgb,var(--sf-tp-color-surface-brand-soft) 26%,var(--sf-tp-color-surface-default)));}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:calc(var(--sf-tp-z-base) - 1)}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-overlay{position:absolute;inset:0;z-index:var(--sf-tp-z-base);background:linear-gradient(90deg,var(--sf-tp-color-surface-brand-soft) 0,var(--sf-tp-color-surface-brand-soft) 44%,color-mix(in srgb,var(--sf-tp-color-surface-brand-soft) 74%,transparent) 53%,color-mix(in srgb,var(--sf-tp-color-surface-brand-soft) 8%,transparent) 68%)}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-copy{position:relative;z-index:var(--sf-tp-z-raised);width:min(calc(var(--sf-tp-container-content-max) - var(--sf-tp-space-16)),56%)}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-copy h1{margin-block:var(--sf-tp-space-2) var(--sf-tp-space-3)}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-lead{color:var(--sf-tp-color-text-secondary);font-size:var(--sf-tp-font-size-lg);line-height:var(--sf-tp-line-height-relaxed);max-width:var(--sf-tp-container-content-max);margin-block-end:var(--sf-tp-space-6)}
|
||||
|
||||
/* 产品目录布局:260px 分类侧栏 + 主列(cms layout-sidebar / side-panel) */
|
||||
.sf-theme-trade-pro .sf-tp-catalogue-layout{display:grid;grid-template-columns:260px 1fr;gap:var(--sf-tp-space-8)}
|
||||
.sf-theme-trade-pro .sf-tp-catalogue-single{display:block}
|
||||
.sf-theme-trade-pro .sf-tp-side-panel{align-self:start;padding:var(--sf-tp-space-5);border-radius:var(--sf-tp-card-border-radius);background:var(--sf-tp-color-surface-muted);position:sticky;top:calc(var(--sf-tp-space-16) + var(--sf-tp-space-16))}
|
||||
.sf-theme-trade-pro .sf-tp-side-panel h3{font-size:var(--sf-tp-font-size-sm);letter-spacing:var(--sf-tp-letter-spacing-wide);text-transform:uppercase;margin-block-end:var(--sf-tp-space-2)}
|
||||
.sf-theme-trade-pro .sf-tp-side-link{display:block;padding:calc(var(--sf-tp-space-4) - var(--sf-tp-space-1)) var(--sf-tp-space-4);border-block-end:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default);font-weight:var(--sf-tp-font-weight-semibold);color:var(--sf-tp-color-text-secondary);font-size:var(--sf-tp-font-size-sm)}
|
||||
.sf-theme-trade-pro .sf-tp-side-link:hover{color:var(--sf-tp-color-text-brand)}
|
||||
.sf-theme-trade-pro .sf-tp-side-link--active{color:var(--sf-tp-color-text-on-brand);background:var(--sf-tp-color-brand-primary);border-radius:var(--sf-tp-radius-xs)}
|
||||
/* 列表栅格 = cms cols-3(主列比首页窄);双类共存时显式压过 Phase 2 的
|
||||
.pro-card 平台着色(更高特异性,与文件顺序无关) */
|
||||
.sf-theme-trade-pro .sf-tp-card-grid--listing{grid-template-columns:repeat(3,minmax(0,1fr))}
|
||||
.sf-theme-trade-pro .sf-tp-card.pro-card{background:var(--sf-tp-color-surface-default);border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-subtle);border-radius:var(--sf-tp-card-border-radius)}
|
||||
/* pro.js 零结果空态注入的 .pro-filter-empty:栅格内整行展示 */
|
||||
.sf-theme-trade-pro .pro-filter-scope>.pro-filter-empty{grid-column:1/-1;padding:var(--sf-tp-space-6);border:var(--sf-tp-border-width-hairline) dashed var(--sf-tp-color-border-default);color:var(--sf-tp-color-text-muted)}
|
||||
|
||||
/* 新闻分支:1fr + 310px 双栏;行 = 290px 封面 + 文本列,行间发丝线分隔 */
|
||||
.sf-theme-trade-pro .sf-tp-news-layout{display:grid;grid-template-columns:1fr 310px;gap:calc(var(--sf-tp-space-8) + var(--sf-tp-space-2))}
|
||||
.sf-theme-trade-pro .sf-tp-news-row{display:grid;grid-template-columns:290px 1fr;gap:var(--sf-tp-space-6);padding-block-end:var(--sf-tp-space-6);margin-block-end:var(--sf-tp-space-6);border-block-end:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default)}
|
||||
/* 行也是 pro-card(pro.js 过滤钩子):还原为无框行形态,压过 Phase 2 着色 */
|
||||
.sf-theme-trade-pro .sf-tp-news-row.pro-card{display:grid;background:transparent;border:0;border-radius:0;overflow:visible;box-shadow:none}
|
||||
.sf-theme-trade-pro .sf-tp-news-row.pro-card:hover{transform:none;box-shadow:none}
|
||||
.sf-theme-trade-pro .sf-tp-news-row .sf-tp-card-media{border-radius:var(--sf-tp-radius-sm);background:var(--sf-tp-color-surface-muted)}
|
||||
.sf-theme-trade-pro .sf-tp-news-row:hover .sf-tp-card-media img{transform:scale(1.04)}
|
||||
.sf-theme-trade-pro .sf-tp-news-body .sf-tp-tag{margin-block-end:var(--sf-tp-space-2)}
|
||||
.sf-theme-trade-pro .sf-tp-news-body h3{font-size:var(--sf-tp-font-size-2xl);margin-block:var(--sf-tp-space-2)}
|
||||
.sf-theme-trade-pro .sf-tp-news-body h3 a{color:inherit}
|
||||
.sf-theme-trade-pro .sf-tp-news-body h3 a:hover{color:var(--sf-tp-color-text-brand)}
|
||||
.sf-theme-trade-pro .sf-tp-news-body p{color:var(--sf-tp-color-text-muted);font-size:var(--sf-tp-font-size-sm);margin-block-end:var(--sf-tp-space-3)}
|
||||
/* 侧栏三盒(cms aside-box):灰底圆角卡 + 右浮计数 */
|
||||
.sf-theme-trade-pro .sf-tp-aside-box{background:var(--sf-tp-color-surface-muted);border-radius:var(--sf-tp-card-border-radius);padding:calc(var(--sf-tp-space-5) + var(--sf-tp-space-1));margin-block-end:var(--sf-tp-space-4)}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box h3{font-size:var(--sf-tp-font-size-md);margin-block-end:var(--sf-tp-space-3)}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box p{margin-block-end:var(--sf-tp-space-3);font-size:var(--sf-tp-font-size-sm)}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box p:last-child{margin-block-end:0}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box a:hover{color:var(--sf-tp-color-text-brand)}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box strong{float:inline-end;color:var(--sf-tp-color-text-brand)}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box ol{padding-inline-start:var(--sf-tp-space-6);margin-block-end:0}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box li{margin-block:var(--sf-tp-space-4);font-size:var(--sf-tp-font-size-sm);color:var(--sf-tp-color-text-muted)}
|
||||
.sf-theme-trade-pro .sf-tp-aside-box li:last-child{margin-block-end:0}
|
||||
|
||||
/* 分页器(cms Pagination):窗口页码 + SVG 箭头,居中可换行 */
|
||||
.sf-theme-trade-pro .sf-tp-pagination{display:flex;justify-content:center;align-items:center;gap:var(--sf-tp-space-1);margin-block-start:var(--sf-tp-space-10);flex-wrap:wrap}
|
||||
.sf-theme-trade-pro .sf-tp-page-num,.sf-theme-trade-pro .sf-tp-page-arrow{display:inline-grid;place-items:center;min-width:36px;height:36px;padding-inline:6px;border-radius:var(--sf-tp-radius-sm);border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-subtle);color:var(--sf-tp-color-text-secondary);font-size:var(--sf-tp-font-size-sm);transition:all var(--sf-tp-duration-fast) var(--sf-tp-easing-standard)}
|
||||
.sf-theme-trade-pro .sf-tp-page-num:hover,.sf-theme-trade-pro .sf-tp-page-arrow:hover:not(.is-disabled){border-color:var(--sf-tp-color-border-brand);color:var(--sf-tp-color-text-brand)}
|
||||
.sf-theme-trade-pro .sf-tp-page-num.is-active{background:var(--sf-tp-color-brand-primary);border-color:var(--sf-tp-color-brand-primary);color:var(--sf-tp-color-text-on-brand);font-weight:var(--sf-tp-font-weight-semibold)}
|
||||
.sf-theme-trade-pro .sf-tp-page-arrow.is-disabled{opacity:.35;cursor:default}
|
||||
.sf-theme-trade-pro .sf-tp-page-dots{color:var(--sf-tp-color-text-muted);padding-inline:2px}
|
||||
|
||||
/* 空列表友好空态(noindex 栏目占位页):居中提示,不渲染筛选/栅格/分页 */
|
||||
.sf-theme-trade-pro .sf-tp-listing-empty{text-align:center;padding:var(--sf-tp-space-12) var(--sf-tp-space-6);border:var(--sf-tp-border-width-hairline) dashed var(--sf-tp-color-border-default);border-radius:var(--sf-tp-card-border-radius);color:var(--sf-tp-color-text-muted)}
|
||||
.sf-theme-trade-pro .sf-tp-listing-empty h2{color:var(--sf-tp-color-text-secondary);margin-block-end:var(--sf-tp-space-3)}
|
||||
|
||||
/* ── listing 响应式(cms 断点:900 双栏堆叠 / 767 hero 竖版 / 620 紧凑)── */
|
||||
@media (max-width: 900px){
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-copy{width:100%}
|
||||
.sf-theme-trade-pro .sf-tp-catalogue-layout{grid-template-columns:1fr}
|
||||
.sf-theme-trade-pro .sf-tp-side-panel{position:static;display:grid;grid-template-columns:repeat(2,1fr);gap:0 var(--sf-tp-space-4)}
|
||||
.sf-theme-trade-pro .sf-tp-news-layout{grid-template-columns:1fr}
|
||||
.sf-theme-trade-pro .sf-tp-news-row{grid-template-columns:240px 1fr}
|
||||
}
|
||||
@media (max-width: 767px){
|
||||
.sf-theme-trade-pro .sf-tp-page-hero{min-height:auto;padding-block:calc(var(--sf-tp-space-12) - var(--sf-tp-space-4)) calc(var(--sf-tp-space-8) + var(--sf-tp-space-2))}
|
||||
}
|
||||
@media (max-width: 620px){
|
||||
.sf-theme-trade-pro .sf-tp-page-hero{padding-block:calc(var(--sf-tp-space-10) + var(--sf-tp-space-4)) calc(var(--sf-tp-space-4) + var(--sf-tp-space-2));align-items:flex-start}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-copy{width:62%}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-copy h1{font-size:28px;line-height:1.05;margin-block-end:8px}
|
||||
.sf-theme-trade-pro .sf-tp-page-hero-lead{font-size:11px;line-height:1.35;margin-block-end:12px}
|
||||
.sf-theme-trade-pro .sf-tp-side-panel{display:block}
|
||||
.sf-theme-trade-pro .sf-tp-news-row{grid-template-columns:1fr}
|
||||
.sf-theme-trade-pro .sf-tp-news-row .sf-tp-card-media{aspect-ratio:16/9}
|
||||
.sf-theme-trade-pro .sf-tp-news-body h3{font-size:var(--sf-tp-font-size-lg)}
|
||||
.sf-theme-trade-pro .sf-tp-news-aside{margin-block-start:var(--sf-tp-space-8)}
|
||||
.sf-theme-trade-pro .sf-tp-page-num,.sf-theme-trade-pro .sf-tp-page-arrow{min-width:32px;height:32px}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user