feat: refine trade-pro variant pages (brand/service/faq/search/notfound)
Task 11 (layout port finale): rebuild the five thin variant pages in the sf-tp design language, informed by upstream industrial/automotive 1.3.0/1.4.0 information architecture. - brand: page-hero (breadcrumb Home > Brands > name, cover bg, anchor button) + related-product card grid (fields.brand == page title) + brand profile body only when authored; derived placeholder summary excluded, empty brands get an empty state, never fabricated intros. - service: page-hero + 1.2/0.8 detail grid (article-body typography + sticky CTA card with contact/back links); empty body collapses to a centered solo column with the CTA card kept. - faq: page-hero + article-body for the rich-text body (platform has no faq content type; sanitize strips details/summary so the typography layer carries it, block-driven details coexist via sf-canvas) + dark contact-guidance card; empty body swaps to an empty state. - search: adopts the same platform mechanism as all four upstream themes (site-runtime.js ?q= client search over dist-root search-index.json); #sf-search/#sf-search-results/#sf-search-count hooks and .sf-search-page kept as JS contract, panel and injected result cards restyled via scoped cms-token overrides. - notfound: branded dark-band 404 (icon macro, giant 404 h1, English copy, back-home + browse-products buttons); no end-cta. CSS: Task 11 block appended to pro.css (new sf-tp-* classes only, own 900/620 media queries; shared hero/grid/typography responsive rules come from existing 10a/10c/10d blocks; search overrides beat factory.css by specificity without touching hooks). Tests: test_trade_pro_variant_pages_structure covers brand fixture (related filtering, empty forms), service/faq body-vs-empty, search mechanism contract + noindex + index asset, 404 structure, v3 spot checks (single h1, chrome, SVG arrows) and clean build report. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -798,6 +798,182 @@ def test_trade_pro_standard_layout_structure(factory):
|
||||
assert ssoup.select_one('.sf-tp-page-hero-lead') is not None # bootstrap 摘要在导语位
|
||||
|
||||
|
||||
def test_trade_pro_variant_pages_structure(factory):
|
||||
# Task 11:brand/service/faq/search/notfound 五个次要页面精修(布局移植
|
||||
# 收官)。设计参照:上游四主题 1.3.0/1.4.0 对应页面的信息架构
|
||||
# (automotive 1.4.0 brand 页最完整:横幅 + 面包屑 + 锚点按钮 + 车型
|
||||
# 网格 + 品牌故事;其余为通用信息页骨架)+ 已建立的 sf-tp 设计语言
|
||||
# (page-hero/面包屑/卡片网格/排版层/空态)。
|
||||
# 数据事实(make_context):brand kind 由 related 提供同品牌产品
|
||||
# (fields.brand == 页题);service/faq 仅页面条目上下文(正文富文本,
|
||||
# sanitize 剥离 details/summary——theme.css 的折叠样式只服务块系统注入
|
||||
# 的 custom_blocks,模板正文只能走排版层);search 为构建器生成的
|
||||
# noindex 静态页(site-runtime.js + search-index.json 的 ?q= 客户端检索,
|
||||
# 上游四主题同款机制,#sf-search/#sf-search-results/#sf-search-count
|
||||
# 三钩子是平台 JS 契约);notfound 走 mode='notfound'(noindex meta)。
|
||||
import re
|
||||
sid = site(factory)
|
||||
assert factory.post(f'/api/factory/sites/{sid}/bootstrap').status_code == 200
|
||||
# ── 数据夹具:显式品牌(正文/封面)+ 2 同品牌产品 + 1 异品牌产品 +
|
||||
# 服务条目(正文/封面)+ FAQ 页(page_template 显式指定)──
|
||||
made = factory.post(f'/api/sites/{sid}/entries', json={
|
||||
'type': 'brand', 'title': 'Quanta', 'route': '/brands/quanta/',
|
||||
'cover': 'https://imgs.example/quanta-hall.jpg',
|
||||
'summary': 'German engineering brand for flow control systems.',
|
||||
'body': '<p>Quanta manufactures flow control systems for export markets.</p><h2>Heritage</h2><p>Founded as an industrial valve maker.</p>'})
|
||||
assert made.status_code in (200, 201), made.text
|
||||
batch = [
|
||||
{'type': 'product', 'title': 'Quanta Valve V1', 'route': '/product/quanta-valve-v1/',
|
||||
'summary': 'Control valve from Quanta.', 'meta': {'fields': {'brand': 'Quanta', 'category': 'Valves'}}},
|
||||
{'type': 'product', 'title': 'Quanta Pump P2', 'route': '/product/quanta-pump-p2/',
|
||||
'summary': 'Centrifugal pump from Quanta.', 'meta': {'fields': {'brand': 'Quanta'}}},
|
||||
{'type': 'product', 'title': 'Rival Actuator A9', 'route': '/product/rival-actuator/',
|
||||
'summary': 'Actuator from another brand.', 'meta': {'fields': {'brand': 'Rival'}}},
|
||||
{'type': 'service', 'title': 'Export Documentation Service', 'route': '/services/export-docs/',
|
||||
'cover': 'https://imgs.example/docs-desk.jpg',
|
||||
'summary': 'Certificates of origin, packing lists and customs paperwork.',
|
||||
'body': '<p>We prepare the complete document set for every shipment.</p><h2>What is included</h2><p>Commercial invoice, packing list and certificate of origin.</p>'},
|
||||
{'type': 'page', 'title': 'Shipping FAQ', 'route': '/faq-shipping/',
|
||||
'summary': 'Frequently asked questions about shipping and documents.',
|
||||
'body': '<p>Answers about lead times and paperwork.</p><h2>How long is the lead time?</h2><p>Standard orders ship in 15 working days.</p>',
|
||||
'meta': {'page_template': 'faq'}},
|
||||
]
|
||||
for row in batch:
|
||||
r = factory.post(f'/api/sites/{sid}/entries', json=row)
|
||||
assert r.status_code in (200, 201), r.text
|
||||
assert factory.put(f'/api/factory/sites/{sid}/theme', json={'theme': 'trade-pro', 'version': '1.0.0'}).status_code == 200
|
||||
bid = factory.post(f'/api/sites/{sid}/builds', json={}).json()['version']
|
||||
|
||||
# ── v3 契约抽验:五种页面 200 / 唯一 h1 / pro-header + pro-footer ──
|
||||
variant_urls = ['/brands/quanta/', '/services/export-docs/', '/faq-shipping/', '/search/', '/404.html']
|
||||
pages = {}
|
||||
for url in variant_urls:
|
||||
r = factory.get(f'/preview/{sid}/{bid}{url}')
|
||||
assert r.status_code == 200, (url, r.text[:200])
|
||||
soup = BeautifulSoup(r.text, 'html.parser')
|
||||
assert len(soup.find_all('h1')) == 1, url
|
||||
assert soup.select_one('.pro-header') and soup.select_one('.pro-footer'), url
|
||||
# 交互箭头一律 SVG(Task 9 契约)
|
||||
assert not re.search(r'[←→↗↘⌕▾]', ''.join(a.get_text() for a in soup.find_all('a'))), url
|
||||
pages[url] = soup
|
||||
|
||||
# ── brand:hero(面包屑 Home › Brands › 品名 + 封面底图 + 锚点按钮)+
|
||||
# 同品牌产品网格(related,异品牌不混入)+ 品牌介绍(正文存在才渲染)──
|
||||
bsoup = pages['/brands/quanta/']
|
||||
hero = bsoup.select_one('section.sf-tp-page-hero.sf-tp-brand-hero')
|
||||
assert hero is not None
|
||||
bg = hero.select_one('.sf-tp-page-hero-bg')
|
||||
assert bg is not None and 'quanta-hall.jpg' in bg.get('src', '')
|
||||
assert hero.select_one('.sf-tp-breadcrumb a[href$="/"]')
|
||||
assert hero.select_one('.sf-tp-breadcrumb a[href$="/brands/"]')
|
||||
assert hero.select_one('.sf-tp-breadcrumb-current').get_text(strip=True) == 'Quanta'
|
||||
assert hero.select_one('.sf-tp-page-hero-copy h1').get_text(strip=True) == 'Quanta'
|
||||
# hero 锚点按钮(automotive 1.4.0 同款信息架构):有产品才渲染
|
||||
assert hero.select_one('.sf-tp-page-hero-copy a.sf-tp-btn[href="#tp-brand-products"]') is not None
|
||||
# 产品网格:related(fields.brand == 页题),异品牌产品不出现在页面上
|
||||
# (groups 无稳定顺序——断言与插入顺序解耦,只验集合内容)
|
||||
grid = bsoup.select_one('.sf-tp-brand-products')
|
||||
assert grid is not None and grid.get('id') == 'tp-brand-products'
|
||||
cards = grid.select('.sf-tp-card-grid .sf-tp-card')
|
||||
assert len(cards) == 2
|
||||
card_titles = {c.select_one('h3').get_text(strip=True) for c in cards}
|
||||
assert card_titles == {'Quanta Valve V1', 'Quanta Pump P2'}
|
||||
assert 'Rival Actuator' not in grid.get_text()
|
||||
assert cards[0].select_one('.sf-tp-card-media') and cards[0].select_one('a.sf-tp-more svg')
|
||||
assert grid.select_one('.sf-tp-section-head a.sf-tp-more[href$="/products/"] svg')
|
||||
# 品牌介绍:body 存在才渲染(排版层双挂);空品牌不虚构介绍
|
||||
profile = bsoup.select_one('.sf-tp-brand-profile .sf-tp-article-body .pro-rich')
|
||||
assert profile is not None and 'Heritage' in profile.get_text()
|
||||
|
||||
# ── service:hero(面包屑 Home › Services › 标题)+ 正文排版层 + CTA 侧卡 ──
|
||||
ssoup = pages['/services/export-docs/']
|
||||
shero = ssoup.select_one('section.sf-tp-page-hero.sf-tp-service-hero')
|
||||
assert shero is not None
|
||||
sbg = shero.select_one('.sf-tp-page-hero-bg')
|
||||
assert sbg is not None and 'docs-desk.jpg' in sbg.get('src', '')
|
||||
assert shero.select_one('.sf-tp-breadcrumb a[href$="/services/"]')
|
||||
assert shero.select_one('.sf-tp-breadcrumb-current').get_text(strip=True) == 'Export Documentation Service'
|
||||
body = ssoup.select_one('.sf-tp-service-body.sf-tp-article-body .pro-rich')
|
||||
assert body is not None and 'What is included' in body.get_text()
|
||||
aside = ssoup.select_one('.sf-tp-service-aside')
|
||||
assert aside is not None
|
||||
assert aside.select_one('a.sf-tp-btn[href$="/contact/"]') is not None # CTA
|
||||
assert aside.select_one('a[href$="/services/"]') is not None # 返回服务列表
|
||||
|
||||
# ── faq:hero + 正文排版层(平台无 faq 内容类型,正文富文本承担)+
|
||||
# 引导联系卡 ──
|
||||
fsoup = pages['/faq-shipping/']
|
||||
fhero = fsoup.select_one('section.sf-tp-page-hero.sf-tp-faq-hero')
|
||||
assert fhero is not None
|
||||
assert fhero.select_one('.sf-tp-breadcrumb a[href$="/faq/"]')
|
||||
fbody = fsoup.select_one('.sf-tp-faq-body.sf-tp-article-body .pro-rich')
|
||||
assert fbody is not None and 'How long is the lead time?' in fbody.get_text()
|
||||
guide = fsoup.select_one('.sf-tp-faq-guide')
|
||||
assert guide is not None and guide.select_one('a.sf-tp-btn[href$="/contact/"]')
|
||||
|
||||
# ── search:与上游四主题同款平台机制(site-runtime.js ?q= 客户端检索
|
||||
# search-index.json),三钩子契约保留 + noindex + sf-tp 化的搜索面板 ──
|
||||
psoup = pages['/search/']
|
||||
assert 'noindex' in str(psoup.find('meta', attrs={'name': 'robots'}))
|
||||
assert psoup.select_one('main#main-content.sf-search-page')
|
||||
assert psoup.select_one('label[for="sf-search"]')
|
||||
inp = psoup.select_one('input#sf-search[type="search"]')
|
||||
assert inp is not None and inp.get('autofocus') is not None
|
||||
assert psoup.select_one('#sf-search-results') is not None
|
||||
assert psoup.select_one('#sf-search-count[aria-live="polite"]') is not None
|
||||
assert psoup.find('h1').get_text(strip=True) == 'Site Search'
|
||||
# 机制资源随构建分发:site-runtime.js 页面引用 + 检索索引含真实内容
|
||||
# (write_assets 把 search-index.json 写在 dist 根,site-runtime.js 以
|
||||
# <base href="/"> 相对解析——检索 URL 契约)
|
||||
sr = factory.get(f'/preview/{sid}/{bid}/search/')
|
||||
assert 'site-runtime.js' in sr.text
|
||||
idx = factory.get(f'/preview/{sid}/{bid}/search-index.json')
|
||||
assert idx.status_code == 200 and 'Quanta Valve V1' in idx.text
|
||||
# search/notfound 无结尾 CTA 带(pro.html 既有分支)
|
||||
assert 'pro-end-cta' not in sr.text
|
||||
|
||||
# ── notfound:品牌化 404(大标题 + 英文文案 + 双按钮 + SVG 图标)──
|
||||
nsoup = pages['/404.html']
|
||||
assert 'noindex' in str(nsoup.find('meta', attrs={'name': 'robots'}))
|
||||
nsec = nsoup.select_one('.sf-tp-notfound')
|
||||
assert nsec is not None
|
||||
assert nsec.find('h1').get_text(strip=True) == '404'
|
||||
assert nsec.select_one('.icon-circle svg') is not None # icon 宏渲染
|
||||
assert nsec.select_one('a.sf-tp-btn[href$="/"]') is not None # Back to home
|
||||
assert nsec.select_one('a[href$="/products/"]') is not None # Browse products
|
||||
assert 'pro-end-cta' not in str(nsoup)
|
||||
|
||||
# 本构建链接全通(新增面包屑/CTA/锚点不产生断链)
|
||||
report = factory.get(f'/api/sites/{sid}/builds/{bid}/report').json()
|
||||
assert not report['errors'] and not report['broken_links'] and not report['missing_local_images']
|
||||
|
||||
# ── 空数据形态:空品牌(无产品/无正文)只显空态不虚构介绍;空服务/
|
||||
# 空 FAQ 正文整段隐藏、CTA/引导保留 ──
|
||||
sid2 = site(factory)
|
||||
for row in [
|
||||
{'type': 'brand', 'title': 'Orphan', 'route': '/brands/orphan/'},
|
||||
{'type': 'service', 'title': 'Placeholder Service', 'route': '/services/placeholder/'},
|
||||
{'type': 'page', 'title': 'Bare FAQ', 'route': '/faq-bare/', 'meta': {'page_template': 'faq'}},
|
||||
]:
|
||||
r = factory.post(f'/api/sites/{sid2}/entries', json=row)
|
||||
assert r.status_code in (200, 201), r.text
|
||||
assert factory.put(f'/api/factory/sites/{sid2}/theme', json={'theme': 'trade-pro', 'version': '1.0.0'}).status_code == 200
|
||||
bid2 = factory.post(f'/api/sites/{sid2}/builds', json={}).json()['version']
|
||||
for url, absent, present in [
|
||||
('/brands/orphan/', ['.sf-tp-brand-products', '.sf-tp-brand-profile', '.sf-tp-card'], ['.sf-tp-listing-empty']),
|
||||
('/services/placeholder/', ['.sf-tp-service-body'], ['.sf-tp-service-aside']),
|
||||
('/faq-bare/', ['.sf-tp-faq-body'], ['.sf-tp-faq-guide']),
|
||||
]:
|
||||
r = factory.get(f'/preview/{sid2}/{bid2}{url}')
|
||||
assert r.status_code == 200, (url, r.text[:200])
|
||||
soup = BeautifulSoup(r.text, 'html.parser')
|
||||
assert len(soup.find_all('h1')) == 1, url
|
||||
for sel in absent:
|
||||
assert soup.select_one(sel) is None, (url, sel)
|
||||
for sel in present:
|
||||
assert soup.select_one(sel) is not None, (url, sel)
|
||||
|
||||
|
||||
def test_trade_pro_chrome_layout(factory):
|
||||
# Task 10j:cms 页眉/页脚 chrome 视觉还原 + 手机端抽屉导航。
|
||||
# 设计源 D:/project/cms/runtimes/astro-site-runtime/src/components/
|
||||
|
||||
@@ -1 +1,85 @@
|
||||
<section class="pro-inner-hero pro-brand-hero"><div class="pro-wrap pro-brand-hero-grid"><div><span class="pro-eyebrow">BRAND PROFILE / PARTNERS</span><h1>{{page.title}}</h1><p>{{page.summary}}</p></div><div class="pro-brand-media">{{cover(page,'brand')}}</div></div></section><section class="pro-section"><div class="pro-wrap">{{body_copy(content,page)}}{% if related %}{{section_title('PRODUCT LINE','Related products','/products/')}}{{grid(related,'product')}}{% endif %}</div></section>
|
||||
{# trade-pro brand detail — 品牌详情精修(Task 11,次要页面收官)。
|
||||
设计参照(本轮无 cms 源对应):上游 themes/automotive/versions/1.4.0/
|
||||
pages/brand.html 的信息架构——品牌横幅(面包屑 + 眉题/h1/导语 + 页内
|
||||
锚点按钮 + 品牌图)→ 车型/产品网格(section heading + "全部"动作位)→
|
||||
品牌故事(眉题 + h2 + 正文);industrial 1.3.0 为同构薄形态。本模板以
|
||||
sf-tp 设计语言重组:sf-tp-page-hero(10c 内页 hero:封面底图 + brand-soft
|
||||
罩层)+ sf-tp-section-head/card-grid(10a 卡片系)+ sf-tp-article-body
|
||||
排版层双挂(10d)。
|
||||
数据事实(make_context 对 brand kind):related = fields.brand 与页题
|
||||
(或 fields.brand 字段)一致的产品/车型集合——品牌页的产品网格只信它;
|
||||
派生品牌页(builder 从产品 brand 字段派生 /brands/<slug>/)body/cover
|
||||
恒空、summary 是平台占位串「相关品牌及产品」——导语按 authored 判定
|
||||
排除占位串(home.html 排除「首页」同款决策),空品牌不虚构介绍:
|
||||
无产品给数据无关的英文导语 + 空态卡,绝不编造品牌故事。
|
||||
面包屑 Brands 链接 /brands/(required_sections 恒保证该路由存在);
|
||||
hero 锚点按钮锚到 #tp-brand-products(构建器豁免 # 锚点,10h 同款)。 #}
|
||||
{% set tp_brand_summary = page.summary if page.summary and page.summary != '相关品牌及产品' else '' %}
|
||||
{# 导语优先级:authored 摘要 > 数据派生计数(Jinja 三元与 or 的优先级易误读,
|
||||
显式分行赋值避免歧义)> 空品牌通用引导 #}
|
||||
{% if tp_brand_summary %}{% set tp_brand_lead = tp_brand_summary %}
|
||||
{% elif related %}{% set tp_brand_lead = ('One product from ' if related|length == 1 else related|length ~ ' products from ') ~ page.title ~ ' — specifications and export documentation included.' %}
|
||||
{% else %}{% set tp_brand_lead = 'Products assigned to this brand in the admin console appear here automatically.' %}{% endif %}
|
||||
<section class="sf-tp-page-hero sf-tp-brand-hero">
|
||||
{% if safe_image(page.cover) %}<img class="sf-tp-page-hero-bg" src="{{ safe_image(page.cover) }}" alt="" width="1600" height="900" fetchpriority="high" decoding="async">{% endif %}
|
||||
<div class="sf-tp-page-hero-overlay" aria-hidden="true"></div>
|
||||
<div class="wrap">
|
||||
<nav class="sf-tp-breadcrumb" aria-label="Breadcrumb" data-reveal>
|
||||
<a href="/">Home</a><a href="/brands/">Brands</a><span class="sf-tp-breadcrumb-current">{{ page.title }}</span>
|
||||
</nav>
|
||||
<div class="sf-tp-page-hero-copy" data-reveal style="--reveal-i: 1">
|
||||
<span class="eyebrow">BRAND PROFILE / PARTNERS</span>
|
||||
<h1>{{ page.title }}</h1>
|
||||
<p class="sf-tp-page-hero-lead">{{ tp_brand_lead }}</p>
|
||||
{% if related %}<a class="sf-tp-btn" href="#tp-brand-products">View brand products {{ icon('arrow-right') }}</a>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% if related %}
|
||||
<section class="section section--soft sf-tp-brand-products" id="tp-brand-products">
|
||||
<div class="wrap">
|
||||
<div class="sf-tp-section-head" data-reveal>
|
||||
<div>
|
||||
<span class="eyebrow">PRODUCT LINE</span>
|
||||
<h2>{{ page.title }} products</h2>
|
||||
</div>
|
||||
<a class="sf-tp-more" href="/products/">All products {{ icon('arrow-right', cls='sf-tp-icon--sm') }}</a>
|
||||
</div>
|
||||
<div class="sf-tp-card-grid">
|
||||
{% for tp_item in related[:8] %}
|
||||
<article class="sf-tp-card" data-reveal style="--reveal-i: {{ loop.index0 % 4 }}">
|
||||
<div class="sf-tp-card-media">{{ cover(tp_item, 'product') }}</div>
|
||||
<div class="sf-tp-card-body">
|
||||
<h3>{{ tp_item.title }}</h3>
|
||||
<p>{{ (tp_item.summary or 'Published specifications available on request.').split('.')[0] }}.</p>
|
||||
<a class="sf-tp-more" href="{{ safe_href(tp_item.route) }}">View details {{ icon('arrow-right', cls='sf-tp-icon--sm') }}</a>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% else %}
|
||||
<section class="section sf-tp-brand-empty-section">
|
||||
<div class="wrap">
|
||||
<div class="sf-tp-listing-empty" data-reveal>
|
||||
<h2>No products listed under this brand yet</h2>
|
||||
<p>Products assigned to this brand appear here automatically once published.</p>
|
||||
<a class="sf-tp-btn sf-tp-btn--ghost" href="/products/">Browse all products {{ icon('arrow-right') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="section sf-tp-brand-profile">
|
||||
<div class="wrap">
|
||||
<div class="sf-tp-section-head" data-reveal>
|
||||
<div>
|
||||
<span class="eyebrow">BRAND PROFILE</span>
|
||||
<h2>About {{ page.title }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sf-tp-brand-body sf-tp-article-body" data-reveal style="--reveal-i: 1">{{ body_copy(content, page) }}</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,2 +1,56 @@
|
||||
<section class="pro-inner-hero pro-info-hero"><div class="pro-wrap"><span class="pro-eyebrow">SUPPORT / FAQ</span><h1>{{page.title}}</h1><p>{{page.summary}}</p></div></section>
|
||||
<section class="pro-section pro-info-section"><div class="pro-wrap pro-info-grid"><div><span class="pro-eyebrow">ANSWERS</span><h2>Frequently asked questions.</h2><p class="pro-muted">Cooperation process, trade terms and common questions.</p></div><div class="pro-info-copy">{{body_copy(content,page)}}{% if page.cover %}<img class="pro-info-photo" src="{{safe_image(page.cover)}}" alt="{{page.title}}">{% endif %}</div></div></section>
|
||||
{# trade-pro faq — FAQ 页精修(Task 11)。
|
||||
设计参照(本轮无 cms 源对应):上游 industrial/automotive 1.3.0/1.4.0 的
|
||||
faq 页与 service 共用通用信息页薄形态;本模板以 sf-tp 设计语言定 FAQ
|
||||
专属口径:sf-tp-page-hero(10c)→ 问题正文(sf-tp-article-body 排版层
|
||||
双挂,10d)→ 深色引导联系卡(找不到答案 → /contact/,10d 侧栏 CTA
|
||||
同款深底白按钮语汇)。
|
||||
数据事实(make_context 对 faq kind):平台无 faq 内容类型——FAQ 页由
|
||||
普通页面条目承担(meta.page_template='faq' 显式指定,或 /faq 前缀路由
|
||||
推断),内容 = 单一富文本 body。sanitize 的 ALLOWED_TAGS 不含
|
||||
details/summary(正文富文本带不进折叠结构);theme.css 的 details/
|
||||
summary 折叠样式(Task 8)服务的是块系统注入的 custom_blocks(编辑器
|
||||
faq 块原生 details 渲染在 sf-canvas 区),与本模板正交共存——模板
|
||||
正文只能走排版层,问题/答案的分节由正文自身 h2/h3 承担(10g/10h 同
|
||||
决策)。body 为空 → 正文区块整段隐藏换空态卡;引导联系卡恒渲染
|
||||
(真实动作位)。面包屑/链接指向 /faq/(required_sections 恒保证;
|
||||
当前页恰为 /faq/ 时自指隐藏)。 #}
|
||||
<section class="sf-tp-page-hero sf-tp-faq-hero">
|
||||
{% if safe_image(page.cover) %}<img class="sf-tp-page-hero-bg" src="{{ safe_image(page.cover) }}" alt="" width="1600" height="900" fetchpriority="high" decoding="async">{% endif %}
|
||||
<div class="sf-tp-page-hero-overlay" aria-hidden="true"></div>
|
||||
<div class="wrap">
|
||||
<nav class="sf-tp-breadcrumb" aria-label="Breadcrumb" data-reveal>
|
||||
<a href="/">Home</a>{% if route != '/faq/' %}<a href="/faq/">FAQ</a>{% endif %}<span class="sf-tp-breadcrumb-current">{{ page.title }}</span>
|
||||
</nav>
|
||||
<div class="sf-tp-page-hero-copy" data-reveal style="--reveal-i: 1">
|
||||
<span class="eyebrow">SUPPORT / FAQ</span>
|
||||
<h1>{{ page.title }}</h1>
|
||||
{% if page.summary %}<p class="sf-tp-page-hero-lead">{{ page.summary }}</p>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section sf-tp-faq">
|
||||
<div class="wrap">
|
||||
{% if content %}
|
||||
<div class="sf-tp-section-head" data-reveal>
|
||||
<div>
|
||||
<span class="eyebrow">ANSWERS</span>
|
||||
<h2>Frequently asked questions</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sf-tp-faq-body sf-tp-article-body" data-reveal style="--reveal-i: 1">{{ body_copy(content, page) }}</div>
|
||||
{% else %}
|
||||
<div class="sf-tp-listing-empty" data-reveal>
|
||||
<h2>No answers published here yet</h2>
|
||||
<p>Questions added to this page in the admin console appear here automatically.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="sf-tp-faq-guide" data-reveal>
|
||||
<div>
|
||||
<span class="eyebrow">STILL NEED HELP?</span>
|
||||
<h3>Can't find your answer?</h3>
|
||||
<p>Send the question directly — replies within one business day.</p>
|
||||
</div>
|
||||
<a class="sf-tp-btn" href="/contact/">Contact us {{ icon('arrow-right') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1 +1,22 @@
|
||||
<section class="pro-404 pro-wrap"><span>ERROR / 404</span><h1>404</h1><p>The page you are looking for does not exist or has been moved.</p><a class="sf-tp-btn" href="/">Back to home {{ icon('arrow-right') }}</a></section>
|
||||
{# trade-pro notfound — 品牌化 404(Task 11)。
|
||||
设计参照(本轮无 cms 源对应):上游 industrial/automotive 1.3.0/1.4.0
|
||||
的 404 为「眉题 + 巨号 404 + 一句文案 + 返回首页」的居中薄形态;本模板
|
||||
保留该信息架构并以 sf-tp 深色带语汇品牌化(10a 应用带的藏青渐变 + 光晕
|
||||
底、反色文案、白底按钮反色),双动作位:返回首页 + 浏览产品目录。
|
||||
渲染流:构建器以 mode='notfound' 渲染(noindex meta),pro.html 对
|
||||
notfound 不渲染结尾 CTA 带;h1 唯一(「404」大标题即页题)。图标走
|
||||
Task 9 icon 宏(search:找不到页面的语义),无裸箭头字符。 #}
|
||||
<section class="sf-tp-notfound">
|
||||
<div class="wrap">
|
||||
<div class="sf-tp-notfound-inner" data-reveal>
|
||||
<div class="icon-circle sf-tp-notfound-icon" aria-hidden="true">{{ icon('search') }}</div>
|
||||
<span class="eyebrow">ERROR / 404</span>
|
||||
<h1>404</h1>
|
||||
<p class="sf-tp-notfound-lead">The page you are looking for does not exist or has been moved.</p>
|
||||
<div class="sf-tp-notfound-actions">
|
||||
<a class="sf-tp-btn" href="/">Back to home {{ icon('arrow-right') }}</a>
|
||||
<a class="sf-tp-btn sf-tp-btn--ghost" href="/products/">Browse products {{ icon('arrow-right') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,2 +1,31 @@
|
||||
<section class="pro-inner-hero"><div class="pro-wrap"><span class="pro-eyebrow">SEARCH / CONTENT</span><h1>Site Search</h1><p>Search products, brands, news and cases across this site.</p></div></section>
|
||||
<main id="main-content" class="sf-search-page pro-wrap"><label for="sf-search">Enter a keyword</label><input type="search" id="sf-search" placeholder="Search products, brands, news, cases..." autofocus><div id="sf-search-count" aria-live="polite"></div><div id="sf-search-results"></div></main>
|
||||
{# trade-pro search — 站内搜索页精修(Task 11)。
|
||||
机制决策:采用与上游四主题完全相同的平台静态检索机制(V8.31 起全主题
|
||||
共享,非 automotive 专属)——构建器为每个构建打包 search-index.json
|
||||
(全站条目标题/摘要/类型/品牌),site-runtime.js 在客户端完成 ?q= 深链
|
||||
读取 + 关键词过滤 + 结果渲染,无任何服务端 API。JS 寻址的是 ID 钩子
|
||||
(#sf-search 输入 / #sf-search-results 容器 / #sf-search-count 计数,
|
||||
factory.css 的 .sf-search-page 提供基线观感)——三钩子与 .sf-search-page
|
||||
类名必须原样保留(平台契约),否则检索退化为一页死输入框。
|
||||
本模板的精修是观感层:hero 换 sf-tp-page-hero(10c 内页 hero 同款浅
|
||||
品牌横幅,搜索是工具页无层级——不带面包屑,与上游一致),搜索面板由
|
||||
pro.css 的 Task 11 作用域规则把 factory.css 的 system-ui 基线覆写为
|
||||
cms 令牌观感(含 site-runtime.js 注入的 .sf-search-result 结果卡)。
|
||||
构建器生成本页时 kind='search'(route 推断先于显式模板),robots 为
|
||||
noindex,follow;pro.html 对 search 页不渲染结尾 CTA 带。页面为英文
|
||||
(构建器的中文页题「站内搜索」仅进 <title>,不进正文)。 #}
|
||||
<section class="sf-tp-page-hero sf-tp-search-hero">
|
||||
<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">SEARCH / CONTENT</span>
|
||||
<h1>Site Search</h1>
|
||||
<p class="sf-tp-page-hero-lead">Search products, brands, news and cases across this site.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<main id="main-content" class="sf-search-page sf-tp-search-panel">
|
||||
<label for="sf-search">Enter a keyword</label>
|
||||
<input type="search" id="sf-search" placeholder="Search products, brands, news, cases..." autofocus>
|
||||
<div id="sf-search-count" aria-live="polite"></div>
|
||||
<div id="sf-search-results"></div>
|
||||
</main>
|
||||
|
||||
@@ -1,2 +1,47 @@
|
||||
<section class="pro-inner-hero pro-info-hero"><div class="pro-wrap"><span class="pro-eyebrow">OUR SERVICES</span><h1>{{page.title}}</h1><p>{{page.summary}}</p></div></section>
|
||||
<section class="pro-section pro-info-section"><div class="pro-wrap pro-info-grid"><div><span class="pro-eyebrow">SERVICE / SUPPORT</span><h2>{{page.title}}</h2><p class="pro-muted">Working process, service scope and support commitments.</p></div><div class="pro-info-copy">{{body_copy(content,page)}}{% if page.cover %}<img class="pro-info-photo" src="{{safe_image(page.cover)}}" alt="{{page.title}}">{% endif %}</div></div></section>
|
||||
{# trade-pro service detail — 服务详情精修(Task 11)。
|
||||
设计参照(本轮无 cms 源对应):上游 industrial/automotive 1.3.0/1.4.0 的
|
||||
service 页为通用信息页薄形态(hero + 双栏正文 + 封面图);本模板以
|
||||
sf-tp 设计语言重组为「详情页」口径:sf-tp-page-hero(10c:封面底图 +
|
||||
面包屑)→ detail 双栏(10g 案例页同构 1.2fr/0.8fr:文案列 = 眉题 + h2 +
|
||||
正文排版层;侧列 = sticky CTA 卡 + 返回服务列表)。
|
||||
数据事实(make_context 对 service kind):仅页面条目上下文(title/
|
||||
summary/body/cover),无服务专属集合;正文 = 单一富文本 body,小节结构
|
||||
由正文自身 h2 承担(10g/10h 同决策),sf-tp-article-body 排版层双挂
|
||||
(10d)。body 为空 → 正文区块整段隐藏,双栏退化为居中单列(CTA 卡
|
||||
保留——真实动作位,非虚构内容)。
|
||||
面包屑/返回链接指向 /services/(required_sections 恒保证该路由存在;
|
||||
当前页恰为 /services/ 时自指链接隐藏,面包屑降级为 Home › 标题)。 #}
|
||||
<section class="sf-tp-page-hero sf-tp-service-hero">
|
||||
{% if safe_image(page.cover) %}<img class="sf-tp-page-hero-bg" src="{{ safe_image(page.cover) }}" alt="" width="1600" height="900" fetchpriority="high" decoding="async">{% endif %}
|
||||
<div class="sf-tp-page-hero-overlay" aria-hidden="true"></div>
|
||||
<div class="wrap">
|
||||
<nav class="sf-tp-breadcrumb" aria-label="Breadcrumb" data-reveal>
|
||||
<a href="/">Home</a>{% if route != '/services/' %}<a href="/services/">Services</a>{% endif %}<span class="sf-tp-breadcrumb-current">{{ page.title }}</span>
|
||||
</nav>
|
||||
<div class="sf-tp-page-hero-copy" data-reveal style="--reveal-i: 1">
|
||||
<span class="eyebrow">SERVICE / SUPPORT</span>
|
||||
<h1>{{ page.title }}</h1>
|
||||
{% if page.summary %}<p class="sf-tp-page-hero-lead">{{ page.summary }}</p>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section sf-tp-service">
|
||||
<div class="wrap sf-tp-service-grid{{ '' if content else ' sf-tp-service-grid--solo' }}">
|
||||
{% if content %}
|
||||
<div class="sf-tp-service-copy" data-reveal>
|
||||
<span class="eyebrow">SERVICE DETAIL</span>
|
||||
<h2>{{ page.title }}</h2>
|
||||
<div class="sf-tp-service-body sf-tp-article-body" data-reveal style="--reveal-i: 1">{{ body_copy(content, page) }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<aside class="sf-tp-service-aside" data-reveal style="--reveal-i: 1">
|
||||
<div class="sf-tp-service-cta">
|
||||
<span class="eyebrow">NEXT STEP</span>
|
||||
<h3>Request this service</h3>
|
||||
<p>Send your requirements and the team replies within one business day.</p>
|
||||
<a class="sf-tp-btn" href="/contact/">Contact us {{ icon('arrow-right') }}</a>
|
||||
</div>
|
||||
{% if route != '/services/' %}<a class="sf-tp-service-back" href="/services/">{{ icon('arrow-left', cls='sf-tp-icon--sm') }} All services</a>{% endif %}
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -745,3 +745,85 @@ body.sf-theme-trade-pro{overflow-x:hidden;overflow-x:clip}
|
||||
.sf-theme-trade-pro .pro-footer-top{grid-template-columns:1fr;gap:var(--sf-tp-space-8)}
|
||||
.sf-theme-trade-pro .pro-footer-bottom{display:block}
|
||||
}
|
||||
|
||||
/* ── Task 11:brand/service/faq/search/notfound 次要页面精修 ──
|
||||
设计参照:上游四主题 1.3.0/1.4.0 对应页的信息架构(automotive 1.4.0
|
||||
brand 页最完整:横幅 + 面包屑 + 锚点按钮 + 车型网格 + 品牌故事;其余为
|
||||
通用信息页骨架)+ 已建立的 sf-tp 设计语言。共享组件零重复声明:
|
||||
brand 的 hero/卡片网格/正文分别由 10c page-hero、10a card-grid、
|
||||
10d article-body 既有规则(含 10a/10c 的 900/767/620 折叠块)覆盖——
|
||||
brand 模板无新增视觉规则;本块只补 service 双栏/CTA 卡、faq 引导卡、
|
||||
search 面板与结果卡、notfound 深色带。级联:全部为 Task 11 新类名的
|
||||
首次声明,位于 10a-10j 既有块之后,无同特异性竞争;search 段按
|
||||
.sf-theme-trade-pro 作用域(0,2,0+)覆写 factory.css 的 .sf-search-page
|
||||
基线(0,1,0)与 site-runtime.js 注入的 .sf-search-result,机制钩子
|
||||
(ID 与类名)不在样式层触碰。 */
|
||||
|
||||
/* service 双栏(10g 案例页 1.2fr/0.8fr 同构):文案列 + sticky CTA 侧列;
|
||||
正文为空时 --solo 单列,CTA 卡居中收窄 */
|
||||
.sf-theme-trade-pro .sf-tp-service-grid{display:grid;grid-template-columns:1.2fr 0.8fr;gap:calc(var(--sf-tp-space-12) + var(--sf-tp-space-4));align-items:start}
|
||||
.sf-theme-trade-pro .sf-tp-service-grid--solo{grid-template-columns:minmax(0,1fr)}
|
||||
.sf-theme-trade-pro .sf-tp-service-grid--solo .sf-tp-service-aside{width:100%;max-width:560px;margin-inline:auto}
|
||||
.sf-theme-trade-pro .sf-tp-service-copy h2{margin-block:var(--sf-tp-space-2) var(--sf-tp-space-6)}
|
||||
.sf-theme-trade-pro .sf-tp-service-aside{position:sticky;top:calc(var(--sf-tp-space-16) + var(--sf-tp-space-4));display:grid;gap:var(--sf-tp-space-4);justify-items:start}
|
||||
.sf-theme-trade-pro .sf-tp-service-cta{display:grid;gap:var(--sf-tp-space-3);padding:var(--sf-tp-card-padding-md);background:var(--sf-tp-color-surface-muted);border-radius:var(--sf-tp-card-border-radius)}
|
||||
.sf-theme-trade-pro .sf-tp-service-cta h3{margin:0;font-size:var(--sf-tp-font-size-xl)}
|
||||
.sf-theme-trade-pro .sf-tp-service-cta p{margin:0;color:var(--sf-tp-color-text-muted);font-size:var(--sf-tp-font-size-sm)}
|
||||
.sf-theme-trade-pro .sf-tp-service-cta .sf-tp-btn{justify-self:start}
|
||||
.sf-theme-trade-pro .sf-tp-service-back{display:inline-flex;align-items:center;gap:var(--sf-tp-space-2);font-size:var(--sf-tp-font-size-sm);font-weight:var(--sf-tp-font-weight-semibold);color:var(--sf-tp-color-text-link)}
|
||||
.sf-theme-trade-pro .sf-tp-service-back:hover{color:var(--sf-tp-color-text-link-hover)}
|
||||
|
||||
/* faq 引导联系卡(10d 侧栏 CTA 深底白按钮语汇):正文之后横排收束 */
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide{display:flex;align-items:center;justify-content:space-between;gap:var(--sf-tp-space-6);flex-wrap:wrap;margin-block-start:var(--sf-tp-space-10);padding:var(--sf-tp-card-padding-md);background:var(--sf-tp-color-surface-inverse);border-radius:var(--sf-tp-card-border-radius);color:var(--sf-tp-color-text-inverse)}
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide .eyebrow{color:var(--sf-tp-color-text-inverse-muted)}
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide h3{margin-block-end:var(--sf-tp-space-2);color:var(--sf-tp-color-text-inverse)}
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide p{margin:0;color:color-mix(in srgb,var(--sf-tp-color-text-inverse) 82%,transparent);font-size:var(--sf-tp-font-size-sm)}
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide .sf-tp-btn{background:var(--sf-tp-color-surface-default);border-color:var(--sf-tp-color-surface-default);color:var(--sf-tp-color-text-brand)}
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide .sf-tp-btn:hover{background:var(--sf-tp-color-brand-primary);border-color:var(--sf-tp-color-brand-primary);color:var(--sf-tp-color-text-on-brand)}
|
||||
/* 空态卡内的按钮(brand 空品牌/browse 产品):与文案拉开间距 */
|
||||
.sf-theme-trade-pro .sf-tp-listing-empty .sf-tp-btn{margin-block-start:var(--sf-tp-space-4)}
|
||||
|
||||
/* search 面板:factory.css 的 .sf-search-page system-ui 基线 → cms 令牌
|
||||
观感(含 site-runtime.js 注入的 .sf-search-result 结果卡样式);
|
||||
#sf-search/#sf-search-results/#sf-search-count 三钩子为平台 JS 契约 */
|
||||
.sf-theme-trade-pro .sf-search-page{min-height:auto;width:min(880px,calc(100% - 32px));margin-inline:auto;padding-block:calc(var(--sf-tp-space-10) + var(--sf-tp-space-4)) calc(var(--sf-tp-space-16) + var(--sf-tp-space-8));font-family:var(--sf-tp-font-family-sans);color:var(--sf-tp-color-text-primary)}
|
||||
.sf-theme-trade-pro .sf-search-page>label{display:block;margin:0 0 var(--sf-tp-space-3);font-size:var(--sf-tp-font-size-xs);font-weight:var(--sf-tp-font-weight-semibold);letter-spacing:var(--sf-tp-letter-spacing-wide);text-transform:uppercase;color:var(--sf-tp-color-text-muted)}
|
||||
.sf-theme-trade-pro .sf-search-page input[type="search"]{display:block;width:100%;padding:var(--sf-tp-space-4) calc(var(--sf-tp-space-4) + var(--sf-tp-space-1));font-size:var(--sf-tp-font-size-lg);font-family:inherit;border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default);border-radius:var(--sf-tp-radius-sm);background:var(--sf-tp-color-surface-default);color:var(--sf-tp-color-text-primary)}
|
||||
.sf-theme-trade-pro .sf-search-page #sf-search-count{margin:var(--sf-tp-space-5) 0 var(--sf-tp-space-3);color:var(--sf-tp-color-text-muted);font-size:var(--sf-tp-font-size-sm)}
|
||||
.sf-theme-trade-pro .sf-search-result{padding:var(--sf-tp-space-5) 0;border-block-end:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-subtle)}
|
||||
.sf-theme-trade-pro .sf-search-result a{color:var(--sf-tp-color-text-primary);font-size:var(--sf-tp-font-size-xl);font-weight:var(--sf-tp-font-weight-bold);text-decoration:none}
|
||||
.sf-theme-trade-pro .sf-search-result a:hover{color:var(--sf-tp-color-text-brand)}
|
||||
.sf-theme-trade-pro .sf-search-result small{display:block;margin-block-start:var(--sf-tp-space-1);color:var(--sf-tp-color-text-brand);font-size:var(--sf-tp-font-size-xs);letter-spacing:var(--sf-tp-letter-spacing-wide);text-transform:uppercase}
|
||||
.sf-theme-trade-pro .sf-search-result p{margin-block-start:var(--sf-tp-space-2);color:var(--sf-tp-color-text-muted);font-size:var(--sf-tp-font-size-sm)}
|
||||
|
||||
/* notfound 深色带(10a 应用带语汇:藏青渐变 + 光晕 + 反色文案):
|
||||
居中单列,巨号 404 为唯一 h1;双按钮(实底 + 深底上的白底反色 ghost) */
|
||||
.sf-theme-trade-pro .sf-tp-notfound{position:relative;overflow:hidden;padding-block:calc(var(--sf-tp-space-16) + var(--sf-tp-space-8)) calc(var(--sf-tp-space-16) + var(--sf-tp-space-4));color:var(--sf-tp-color-text-inverse);background:linear-gradient(115deg,var(--sf-tp-color-surface-inverse),var(--sf-tp-color-brand-primary-deep) 78%)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound::before{content:"";position:absolute;inset:0;background:radial-gradient(circle at 15% 20%,color-mix(in srgb,var(--sf-tp-color-brand-primary) 24%,transparent),transparent 42%);pointer-events:none}
|
||||
.sf-theme-trade-pro .sf-tp-notfound .wrap{position:relative;z-index:var(--sf-tp-z-raised)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-inner{display:grid;justify-items:center;max-width:560px;margin-inline:auto;text-align:center}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-inner .eyebrow{color:var(--sf-tp-color-text-inverse-muted)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-inner h1{margin-block:var(--sf-tp-space-2) var(--sf-tp-space-3);font-size:clamp(120px,22vw,220px);line-height:.9;letter-spacing:var(--sf-tp-letter-spacing-tight);color:var(--sf-tp-color-text-inverse)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-icon{background:color-mix(in srgb,var(--sf-tp-color-neutral-0) 12%,transparent);color:var(--sf-tp-color-text-inverse)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-lead{color:color-mix(in srgb,var(--sf-tp-color-text-inverse) 88%,transparent);font-size:var(--sf-tp-font-size-lg);margin-block-end:var(--sf-tp-space-8)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-actions{display:flex;gap:var(--sf-tp-space-4);flex-wrap:wrap;justify-content:center}
|
||||
.sf-theme-trade-pro .sf-tp-notfound .sf-tp-btn--ghost{background:var(--sf-tp-color-surface-default);border-color:var(--sf-tp-color-surface-default);color:var(--sf-tp-color-text-brand)}
|
||||
|
||||
/* ── Task 11 响应式(新类名折叠收本块;hero 竖版/卡片栅格/正文紧凑由
|
||||
10c/10a/10d 既有媒体块经共用类名覆盖——10c 教训:同特异性按源顺序
|
||||
取胜,本块只声明 Task 11 新类名)── */
|
||||
@media (max-width: 900px){
|
||||
.sf-theme-trade-pro .sf-tp-service-grid{grid-template-columns:1fr;gap:var(--sf-tp-space-8)}
|
||||
.sf-theme-trade-pro .sf-tp-service-aside{position:static}
|
||||
}
|
||||
@media (max-width: 620px){
|
||||
.sf-theme-trade-pro .sf-tp-service-cta{padding:16px}
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide{display:block}
|
||||
.sf-theme-trade-pro .sf-tp-faq-guide .sf-tp-btn{margin-block-start:12px}
|
||||
.sf-theme-trade-pro .sf-search-page{padding-block:28px 72px}
|
||||
.sf-theme-trade-pro .sf-search-page input[type="search"]{padding:13px 16px;font-size:var(--sf-tp-font-size-md)}
|
||||
.sf-theme-trade-pro .sf-search-result a{font-size:var(--sf-tp-font-size-lg)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound{padding-block:64px 56px}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-inner h1{font-size:clamp(96px,26vw,140px)}
|
||||
.sf-theme-trade-pro .sf-tp-notfound-actions{display:grid;grid-template-columns:1fr;justify-items:stretch}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user