From 5797638caf65e7740b5fc52d243b0e73b46c0c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Thu, 22 Oct 2026 18:19:30 +0800 Subject: [PATCH] feat: trade-pro skeleton theme package (Phase 2) Fifth built-in theme: English-first international B2B skeleton registered via manifest discovery, builds real sites end-to-end. pro.html derives from industrial with lang=en, href-set value-comparison English fallback nav (header + footer), sf-tp-* button classes and hard-coded #0b3d91 theme-color until the map entry lands. pages/ ships all 14 kinds; macro library is an English passthrough copy pending the Phase 3 cms port. Co-Authored-By: Claude Code --- tests/test_theme_registry.py | 21 ++ .../trade-pro/_professional_components.html | 19 ++ themes/trade-pro/blocks.css | 1 + themes/trade-pro/manifest.json | 16 + themes/trade-pro/page-presets.json | 285 ++++++++++++++++++ themes/trade-pro/pages/about.html | 2 + themes/trade-pro/pages/article.html | 1 + themes/trade-pro/pages/brand.html | 1 + themes/trade-pro/pages/case.html | 1 + themes/trade-pro/pages/category.html | 2 + themes/trade-pro/pages/contact.html | 6 + themes/trade-pro/pages/faq.html | 2 + themes/trade-pro/pages/home.html | 8 + themes/trade-pro/pages/listing.html | 2 + themes/trade-pro/pages/notfound.html | 1 + themes/trade-pro/pages/product.html | 3 + themes/trade-pro/pages/search.html | 2 + themes/trade-pro/pages/service.html | 2 + themes/trade-pro/pages/standard.html | 2 + themes/trade-pro/pro.css | 32 ++ themes/trade-pro/pro.html | 20 ++ themes/trade-pro/site.html | 12 + themes/trade-pro/theme.css | 15 + themes/trade-pro/versions/.gitkeep | 0 themes/trade-pro/visual/.gitkeep | 0 25 files changed, 456 insertions(+) create mode 100644 themes/trade-pro/_professional_components.html create mode 100644 themes/trade-pro/blocks.css create mode 100644 themes/trade-pro/manifest.json create mode 100644 themes/trade-pro/page-presets.json create mode 100644 themes/trade-pro/pages/about.html create mode 100644 themes/trade-pro/pages/article.html create mode 100644 themes/trade-pro/pages/brand.html create mode 100644 themes/trade-pro/pages/case.html create mode 100644 themes/trade-pro/pages/category.html create mode 100644 themes/trade-pro/pages/contact.html create mode 100644 themes/trade-pro/pages/faq.html create mode 100644 themes/trade-pro/pages/home.html create mode 100644 themes/trade-pro/pages/listing.html create mode 100644 themes/trade-pro/pages/notfound.html create mode 100644 themes/trade-pro/pages/product.html create mode 100644 themes/trade-pro/pages/search.html create mode 100644 themes/trade-pro/pages/service.html create mode 100644 themes/trade-pro/pages/standard.html create mode 100644 themes/trade-pro/pro.css create mode 100644 themes/trade-pro/pro.html create mode 100644 themes/trade-pro/site.html create mode 100644 themes/trade-pro/theme.css create mode 100644 themes/trade-pro/versions/.gitkeep create mode 100644 themes/trade-pro/visual/.gitkeep diff --git a/tests/test_theme_registry.py b/tests/test_theme_registry.py index 30fd719..99fbaf9 100644 --- a/tests/test_theme_registry.py +++ b/tests/test_theme_registry.py @@ -2,6 +2,7 @@ import json from pathlib import Path from app import core, theme_pro, theme_store +from test_factory_v2 import factory, site # noqa: F401 -- fixture + helper reused by trade-pro tests ROOT = Path(core.__file__).resolve().parent.parent @@ -92,6 +93,26 @@ def test_env_for_degraded_branch_not_cached_and_single_path(tmp_path, monkeypatc finally: core.THEMES = core.discover_themes() +def test_trade_pro_registered_and_compatible(): + assert 'trade-pro' in core.THEMES + result = theme_store.compatibility('trade-pro') + assert result['valid'], result['errors'] + assert not result['errors'] + +def test_trade_pro_builds_real_site(factory): + sid = site(factory) + assert factory.post(f'/api/factory/sites/{sid}/bootstrap').status_code == 200 + selected = factory.put(f'/api/factory/sites/{sid}/theme', json={'theme': 'trade-pro', 'version': '1.0.0'}) + assert selected.status_code == 200, selected.text + result = factory.post(f'/api/sites/{sid}/builds', json={}) + assert result.status_code == 200, result.text + bid = result.json()['version'] + home = factory.get(f'/preview/{sid}/{bid}/') + assert home.status_code == 200, home.text[:400] + assert 'lang="en"' in home.text + assert '>首页<' not in home.text + assert ' + {% else %}
{{ (item.title or 'SF')[:2] }}{{ kind|upper }}
{% endif %} +{% endmacro %} +{% macro card(item, kind='product', position=0) %} + +
{{ cover(item,kind) }}
+
{{ fields_of(item).get('brand') or fields_of(item).get('category') or {'product':'PRODUCT','vehicle':'VEHICLE','post':'NEWS','case':'CASE','brand':'BRAND','service':'SERVICE'}.get(item.type,'CONTENT') }}{{ '%02d'|format(position+1) }}
+

{{ item.title }}

{{ (item.summary or '')[:128] }}

View details
+
+{% endmacro %} +{% macro grid(items,kind='product') %}
{% for item in items %}{{ card(item,kind,loop.index0) }}{% else %}
No published content in this section yet.
{% endfor %}
{% endmacro %} +{% macro section_title(eyebrow,heading,href='') %}
{{ eyebrow }}

{{ heading }}

{% if href %}Browse all ↗{% endif %}
{% endmacro %} +{% macro filters() %}
{% endmacro %} +{% macro footer_links(nav) %}{% endmacro %} +{% macro body_copy(content,page) %}{% if content %}
{{ content }}
{% elif page.summary %}

{{ page.summary }}

{% else %}

Complete this page's content in the admin console.

{% endif %}{% endmacro %} diff --git a/themes/trade-pro/blocks.css b/themes/trade-pro/blocks.css new file mode 100644 index 0000000..cb661c9 --- /dev/null +++ b/themes/trade-pro/blocks.css @@ -0,0 +1 @@ +/* trade-pro component styles: filled in Phase 3 */ diff --git a/themes/trade-pro/manifest.json b/themes/trade-pro/manifest.json new file mode 100644 index 0000000..4736eed --- /dev/null +++ b/themes/trade-pro/manifest.json @@ -0,0 +1,16 @@ +{ + "id": "trade-pro", + "name": "Trade Pro — International B2B", + "description": "English-first international B2B theme: responsive trade catalogue, product specs and inquiry CTA.", + "version": "1.0.0", + "style": "international-b2b", + "entry": "pro.html", + "styles": ["theme.css", "blocks.css"], + "page_templates": ["home","about","contact","listing","category","product","article","brand","case","service","faq","standard","notfound"], + "blocks": ["hero","richtext","features","stats","collection","image_text","gallery","faq","cta","attributes","spacer","layout","carousel","video","tabs","pricing","map","form_link"], + "responsive": true, + "auto_binding": true, + "professional_layout": true, + "commercial_ui": true, + "accent": "#0b3d91" +} diff --git a/themes/trade-pro/page-presets.json b/themes/trade-pro/page-presets.json new file mode 100644 index 0000000..8ae1aa6 --- /dev/null +++ b/themes/trade-pro/page-presets.json @@ -0,0 +1,285 @@ +{ + "home": [ + { + "id": "0cdf18bf7f", + "type": "hero", + "visible": true, + "title": "工程质量,值得信赖", + "subtitle": "INDUSTRIAL ENGINEERING", + "description": "{{site.tagline}}", + "button": "查看产品", + "href": "/product/", + "align": "left" + }, + { + "id": "f846a2ff6b", + "type": "features", + "visible": true, + "title": "制造与服务能力", + "items": [ + { + "title": "专业服务", + "text": "从咨询到交付" + }, + { + "title": "品质保障", + "text": "严格的质量流程" + }, + { + "title": "全球网络", + "text": "连接不同市场" + } + ] + }, + { + "id": "ff4655d684", + "type": "collection", + "visible": true, + "title": "工业产品系列", + "subtitle": "PRODUCT SOLUTIONS", + "source": "product", + "limit": 6, + "columns": 3, + "button": "查看全部", + "href": "/product/" + }, + { + "id": "4355daaba0", + "type": "image_text", + "visible": true, + "title": "工程标准与服务流程", + "subtitle": "QUALITY FIRST", + "description": "展示业务流程和服务理念。", + "image": "", + "image_side": "right", + "button": "了解更多", + "href": "/about/" + }, + { + "id": "9e5056370d", + "type": "cta", + "visible": true, + "title": "获取专业产品方案", + "subtitle": "告诉我们您的需求,我们将提供适合的方案。", + "button": "联系我们", + "href": "/contact/" + } + ], + "about": [ + { + "id": "8ced1e0493", + "type": "image_text", + "visible": true, + "title": "认识我们", + "subtitle": "OUR APPROACH", + "description": "展示业务流程和服务理念。", + "image": "", + "image_side": "right", + "button": "了解更多", + "href": "/about/" + }, + { + "id": "52b6064084", + "type": "stats", + "visible": true, + "title": "我们的实力", + "items": [ + { + "value": "50,000+", + "label": "服务案例" + }, + { + "value": "70+", + "label": "市场覆盖" + }, + { + "value": "30+", + "label": "合作伙伴" + } + ] + }, + { + "id": "cf39bcb75d", + "type": "features", + "visible": true, + "title": "我们的优势", + "items": [ + { + "title": "专业服务", + "text": "从咨询到交付" + }, + { + "title": "品质保障", + "text": "严格的质量流程" + }, + { + "title": "全球网络", + "text": "连接不同市场" + } + ] + } + ], + "contact": [ + { + "id": "597f6ffb08", + "type": "richtext", + "visible": true, + "title": "联系我们", + "body": "

请填写企业联系方式与地址。

" + }, + { + "id": "8c02c61415", + "type": "cta", + "visible": true, + "title": "欢迎联系", + "subtitle": "告诉我们您的需求,我们将提供适合的方案。", + "button": "联系我们", + "href": "/contact/" + } + ], + "listing": [ + { + "id": "2c3106baf6", + "type": "collection", + "visible": true, + "title": "工业产品目录", + "subtitle": "为客户提供适合的解决方案", + "source": "product", + "limit": 24, + "columns": 3, + "button": "查看全部", + "href": "/product/" + } + ], + "product": [ + { + "id": "42925dc8e3", + "type": "image_text", + "visible": true, + "title": "产品介绍", + "subtitle": "OUR APPROACH", + "description": "{{page.summary}}", + "image": "{{page.cover}}", + "image_side": "right", + "button": "了解更多", + "href": "/about/" + }, + { + "id": "503266af35", + "type": "attributes", + "visible": true, + "title": "产品规格与参数" + }, + { + "id": "b2b1f5293c", + "type": "richtext", + "visible": true, + "title": "产品详情", + "body": "{{page.body}}" + }, + { + "id": "3837f66074", + "type": "cta", + "visible": true, + "title": "开启新的合作", + "subtitle": "告诉我们您的需求,我们将提供适合的方案。", + "button": "联系我们", + "href": "/contact/" + } + ], + "article": [ + { + "id": "c2573cb88d", + "type": "richtext", + "visible": true, + "title": "{{page.title}}", + "body": "{{page.body}}" + } + ], + "brand": [ + { + "id": "f43b705317", + "type": "image_text", + "visible": true, + "title": "{{page.title}}", + "subtitle": "OUR APPROACH", + "description": "{{page.summary}}", + "image": "{{page.cover}}", + "image_side": "right", + "button": "了解更多", + "href": "/about/" + }, + { + "id": "b3faf08170", + "type": "collection", + "visible": true, + "title": "品牌产品", + "subtitle": "为客户提供适合的解决方案", + "source": "product", + "limit": 6, + "columns": 3, + "button": "查看全部", + "href": "/product/" + } + ], + "standard": [ + { + "id": "7937550319", + "type": "richtext", + "visible": true, + "title": "{{page.title}}", + "body": "{{page.body}}" + } + ], + "notfound": [ + { + "id": "59383d762e", + "type": "cta", + "visible": true, + "title": "页面暂时无法访问", + "subtitle": "告诉我们您的需求,我们将提供适合的方案。", + "button": "返回首页", + "href": "/" + } + ], + "case": [ + { + "type": "image_text", + "title": "{{page.title}}", + "image": "{{page.cover}}", + "description": "{{page.summary}}" + }, + { + "type": "richtext", + "title": "项目概述", + "body": "{{page.body}}" + } + ], + "service": [ + { + "type": "richtext", + "title": "{{page.title}}", + "body": "{{page.body}}" + }, + { + "type": "cta", + "title": "了解更多", + "href": "/contact/" + } + ], + "faq": [ + { + "type": "faq", + "title": "常见问题", + "items": [] + } + ], + "category": [ + { + "type": "collection", + "title": "分类产品", + "source": "product", + "limit": 24 + } + ] +} \ No newline at end of file diff --git a/themes/trade-pro/pages/about.html b/themes/trade-pro/pages/about.html new file mode 100644 index 0000000..a08a6b0 --- /dev/null +++ b/themes/trade-pro/pages/about.html @@ -0,0 +1,2 @@ +
OUR STORY

{{page.title}}

{{page.summary}}

+
ABOUT / DISCOVER

Who we are.

Company profile, capabilities and export experience.

{{body_copy(content,page)}}{% if page.cover %}{{page.title}}{% endif %}
diff --git a/themes/trade-pro/pages/article.html b/themes/trade-pro/pages/article.html new file mode 100644 index 0000000..dfca60f --- /dev/null +++ b/themes/trade-pro/pages/article.html @@ -0,0 +1 @@ +
LATEST NEWS / INSIGHTS

{{page.title}}

{{page.summary}}

{% if fields.get('publish_date') %}{% endif %}
diff --git a/themes/trade-pro/pages/brand.html b/themes/trade-pro/pages/brand.html new file mode 100644 index 0000000..9705456 --- /dev/null +++ b/themes/trade-pro/pages/brand.html @@ -0,0 +1 @@ +
BRAND PROFILE / PARTNERS

{{page.title}}

{{page.summary}}

{{cover(page,'brand')}}
{{body_copy(content,page)}}{% if related %}{{section_title('PRODUCT LINE','Related products','/products/')}}{{grid(related,'product')}}{% endif %}
diff --git a/themes/trade-pro/pages/case.html b/themes/trade-pro/pages/case.html new file mode 100644 index 0000000..7c16d86 --- /dev/null +++ b/themes/trade-pro/pages/case.html @@ -0,0 +1 @@ +
SELECTED WORK / PROJECT

{{page.title}}

{{page.summary}}

{% if page.cover %}{{page.title}}{% endif %}
{% if fields.get('location') %}Location
{{fields.get('location')}}
{% endif %}{% if fields.get('industry') %}Industry
{{fields.get('industry')}}
{% endif %}
{{body_copy(content,page)}}Browse more projects →
diff --git a/themes/trade-pro/pages/category.html b/themes/trade-pro/pages/category.html new file mode 100644 index 0000000..8b2ea73 --- /dev/null +++ b/themes/trade-pro/pages/category.html @@ -0,0 +1,2 @@ +
DISCOVER / {{'CATEGORY' if kind=='category' else 'COLLECTION'}}

{{page.title}}

{{page.summary or 'Browse all published content in this section.'}}

Home/{{page.title}}
+
{{ filters() }}
{{grid(listing,'catalog')}}
{% if pagination and pagination.pages>1 %}{% endif %}
diff --git a/themes/trade-pro/pages/contact.html b/themes/trade-pro/pages/contact.html new file mode 100644 index 0000000..b4ef08b --- /dev/null +++ b/themes/trade-pro/pages/contact.html @@ -0,0 +1,6 @@ +
GET IN TOUCH

{{page.title}}

{{page.summary}}

+
CONNECT / CONTACT

Let's start the conversation.

{% if footer_email %}{{footer_email}} ↗{% else %}

Set the official business email in the site admin console first.

{% endif %}
{{body_copy(content,page)}}{% if page.cover %}{{page.title}}{% endif %}
+{% if form_endpoint %} +
CONTACT FORM

Send a business enquiry

Submissions go directly to the external form service configured by the site administrator.

+

Form submissions are handled by the external service; review its privacy and spam-filtering settings.

+{% endif %} diff --git a/themes/trade-pro/pages/faq.html b/themes/trade-pro/pages/faq.html new file mode 100644 index 0000000..6db86e9 --- /dev/null +++ b/themes/trade-pro/pages/faq.html @@ -0,0 +1,2 @@ +
SUPPORT / FAQ

{{page.title}}

{{page.summary}}

+
ANSWERS

Frequently asked questions.

Cooperation process, trade terms and common questions.

{{body_copy(content,page)}}{% if page.cover %}{{page.title}}{% endif %}
diff --git a/themes/trade-pro/pages/home.html b/themes/trade-pro/pages/home.html new file mode 100644 index 0000000..dc522a6 --- /dev/null +++ b/themes/trade-pro/pages/home.html @@ -0,0 +1,8 @@ + +
GLOBAL SOURCING · MADE RELIABLE / 001

{{page.title if page.title not in (site.name,'首页','Home') else site.name}} BUILT FOR GLOBAL TRADE.

{{page.summary or site.tagline or 'Reliable products, transparent specifications and responsive export service.'}}

{% if page.cover %}{{page.title}}{% else %}
EXPORT / B2B
{% endif %}
+{% if categories %}
{{section_title('PRODUCT CATEGORIES','Shop by category','/products/')}}
{% for cat in categories[:6] %}0{{loop.index}}{{cat.name}}↗{% endfor %}
{% endif %} + +
SERVICE & SUPPORT

From inquiry to delivery.

{{site.tagline or 'Product specifications, quality control and export documentation in one place.'}}

About our company ↗
diff --git a/themes/trade-pro/pages/listing.html b/themes/trade-pro/pages/listing.html new file mode 100644 index 0000000..8b2ea73 --- /dev/null +++ b/themes/trade-pro/pages/listing.html @@ -0,0 +1,2 @@ +
DISCOVER / {{'CATEGORY' if kind=='category' else 'COLLECTION'}}

{{page.title}}

{{page.summary or 'Browse all published content in this section.'}}

Home/{{page.title}}
+
{{ filters() }}
{{grid(listing,'catalog')}}
{% if pagination and pagination.pages>1 %}{% endif %}
diff --git a/themes/trade-pro/pages/notfound.html b/themes/trade-pro/pages/notfound.html new file mode 100644 index 0000000..abf2674 --- /dev/null +++ b/themes/trade-pro/pages/notfound.html @@ -0,0 +1 @@ +
ERROR / 404

404

The page you are looking for does not exist or has been moved.

Back to home ↗
diff --git a/themes/trade-pro/pages/product.html b/themes/trade-pro/pages/product.html new file mode 100644 index 0000000..d8c451a --- /dev/null +++ b/themes/trade-pro/pages/product.html @@ -0,0 +1,3 @@ +
Home/Products/{{page.title}}
+
PRODUCT DETAILS / {{fields.get('brand') or 'CATALOGUE'}}

{{page.title}}

{{page.summary or 'Detailed product information and specifications.'}}

{% if fields.get('brand') %}

Brand · {{fields.get('brand')}}

{% endif %}Inquire about this product ↗
+
OVERVIEW

Product overview

{{body_copy(content,page)}}
SPECIFICATIONS

Specifications

{% for row in specs %}
{{row.label}}{{row.value}}
{% else %}

Specifications have not been filled in yet.

{% endfor %}
diff --git a/themes/trade-pro/pages/search.html b/themes/trade-pro/pages/search.html new file mode 100644 index 0000000..56a6217 --- /dev/null +++ b/themes/trade-pro/pages/search.html @@ -0,0 +1,2 @@ +
SEARCH / CONTENT

Site Search

Search products, brands, news and cases across this site.

+
diff --git a/themes/trade-pro/pages/service.html b/themes/trade-pro/pages/service.html new file mode 100644 index 0000000..2f57ad8 --- /dev/null +++ b/themes/trade-pro/pages/service.html @@ -0,0 +1,2 @@ +
OUR SERVICES

{{page.title}}

{{page.summary}}

+
SERVICE / SUPPORT

{{page.title}}

Working process, service scope and support commitments.

{{body_copy(content,page)}}{% if page.cover %}{{page.title}}{% endif %}
diff --git a/themes/trade-pro/pages/standard.html b/themes/trade-pro/pages/standard.html new file mode 100644 index 0000000..4194db0 --- /dev/null +++ b/themes/trade-pro/pages/standard.html @@ -0,0 +1,2 @@ +
COMPANY / EXPLORE

{{page.title}}

{{page.summary}}

+
OVERVIEW

{{page.title}}

Applications, support material and company information.

{{body_copy(content,page)}}{% if page.cover %}{{page.title}}{% endif %}
diff --git a/themes/trade-pro/pro.css b/themes/trade-pro/pro.css new file mode 100644 index 0000000..c1f53e3 --- /dev/null +++ b/themes/trade-pro/pro.css @@ -0,0 +1,32 @@ +/* trade-pro pro.css — skeleton layer (Phase 2). + Kept above the 2 KB floor every built-in theme must satisfy for the + packaged asset assertion (tests/test_theme_pro_v3.py). The full cms port + (tokens/base/components) lands in Phase 3; until then these rules only + tint the shared pro-base.css chrome with trade-pro tokens. */ +.sf-theme-trade-pro .pro-wrap{max-width:1200px;margin:0 auto;padding:0 20px} +.sf-theme-trade-pro .pro-header{background:#fff;border-bottom:3px solid var(--sf-tp-primary,#0b3d91)} +.sf-theme-trade-pro .pro-logo-name small{color:var(--sf-tp-primary,#0b3d91);letter-spacing:.18em} +.sf-theme-trade-pro .pro-navigation a{color:var(--sf-tp-text,#1a2332);text-decoration:none;font-weight:500} +.sf-theme-trade-pro .pro-navigation a:hover{color:var(--sf-tp-primary,#0b3d91)} +.sf-theme-trade-pro .pro-header-cta{white-space:nowrap} +.sf-theme-trade-pro .pro-mega{border-top:1px solid #e3e9f2;background:#f7fafd} +.sf-theme-trade-pro .pro-mega a{color:var(--sf-tp-primary,#0b3d91)} +.sf-theme-trade-pro .pro-category-tiles a{border:1px solid #dfe7f2;border-radius:var(--sf-tp-radius,8px);background:#fff} +.sf-theme-trade-pro .pro-category-tiles a span{color:var(--sf-tp-accent,#f5a623)} +.sf-theme-trade-pro .pro-card{border:1px solid #dfe7f2;border-radius:var(--sf-tp-radius,8px);background:#fff;overflow:hidden} +.sf-theme-trade-pro .pro-card h3{color:var(--sf-tp-text,#1a2332)} +.sf-theme-trade-pro .pro-card:hover{border-color:var(--sf-tp-primary,#0b3d91)} +.sf-theme-trade-pro .pro-card-link{color:var(--sf-tp-primary,#0b3d91)} +.sf-theme-trade-pro .pro-specs div{border-bottom:1px solid #e3e9f2} +.sf-theme-trade-pro .pro-specs span{color:var(--sf-tp-muted,#5a6a7e)} +.sf-theme-trade-pro .pro-end-cta{background:var(--sf-tp-primary,#0b3d91);color:#fff} +.sf-theme-trade-pro .pro-end-cta .pro-eyebrow{color:var(--sf-tp-accent,#f5a623)} +.sf-theme-trade-pro .pro-end-cta .sf-tp-btn{background:#fff;color:var(--sf-tp-primary,#0b3d91);border-color:#fff} +.sf-theme-trade-pro .pro-footer{background:#0d1b2e;color:#c7d3e2} +.sf-theme-trade-pro .pro-footer h2{color:#fff} +.sf-theme-trade-pro .pro-footer a{color:#fff} +.sf-theme-trade-pro .pro-footer-bottom{border-top:1px solid #24344c} +.sf-theme-trade-pro .pro-filter-panel{border:1px solid #dfe7f2;border-radius:var(--sf-tp-radius,8px)} +.sf-theme-trade-pro .pro-404 strong{color:var(--sf-tp-primary,#0b3d91)} +/* Phase 3: replace the tint layer above with the ported cms base.css and + components (tokens prefixed --sf-tp-, all interactive classes sf-tp-*). */ diff --git a/themes/trade-pro/pro.html b/themes/trade-pro/pro.html new file mode 100644 index 0000000..3c3032f --- /dev/null +++ b/themes/trade-pro/pro.html @@ -0,0 +1,20 @@ +{{ seo_title }}{% if canonical %}{% endif %}{# Skeleton: hard-coded theme color; switch back to the theme_color context variable once the platform map gains a trade-pro entry (Task 6). #}{% if canonical and not noindex %}{% endif %}{% if theme_overrides %}{% endif %}Skip to content +{% from '_professional_components.html' import card,cover,grid,section_title,filters,footer_links,body_copy with context %} +{# English fallback navigation (skeleton): the platform always fills nav with + Chinese defaults (首页/产品/品牌/新闻/案例/关于/联系) unless the site configured + its own navigation or published a site design. Detect "unconfigured" by + comparing the nav href set against the platform default href set (identical + for the make_context default and the bootstrap navigation), then render the + English fallback list. Routes are limited to sections every build + guarantees, so no fallback link can become a broken link. #} +{% set tp_default_hrefs=['/','/about/','/brands/','/cases/','/contact/','/news/','/products/'] %} +{% set tp_needs_en_nav=(not chrome_is_custom) and (nav|map(attribute='route')|list|sort==tp_default_hrefs) %} +{% set tp_nav=[{'title':'Home','route':'/'},{'title':'Products','route':'/products/'},{'title':'News','route':'/news/'},{'title':'About','route':'/about/'},{'title':'Contact','route':'/contact/'}] if tp_needs_en_nav else nav %} +{% if chrome_is_custom %}
{{ chrome.header.announcement }}{{ site.tagline or site.name }}
{% else %}
GLOBAL SOURCING · QUALITY · DELIVERYINTERNATIONAL B2B SOLUTIONS
{% endif %} +
{% if chrome_is_custom %}{% if chrome.header.show_cta %}{{chrome.header.cta_text}} ↗{% endif %}{% else %}Request a Quote ↗{% endif %}
{% if categories %}{% endif %}
+{% if not designer_replace %}{% include 'trade-pro/pages/' ~ kind ~ '.html' %}{% endif %} + +{% if has_custom and kind!='notfound' %}
{{custom_blocks}}
{% else %}
{% endif %} +{% if kind not in ('notfound','search') %}
LET'S CONNECT

Ready to source with confidence?

{{site.tagline or 'Send your specifications and get a quotation within one business day.'}}

Contact us ↗
{% endif %} +
+ diff --git a/themes/trade-pro/site.html b/themes/trade-pro/site.html new file mode 100644 index 0000000..630bab5 --- /dev/null +++ b/themes/trade-pro/site.html @@ -0,0 +1,12 @@ +{{seo_title}}{% if canonical %}{% endif %} +
ENGINEERING · MANUFACTURING · SUPPLYGLOBAL INDUSTRIAL SOLUTIONS
+
▰{{site.name}}INDUSTRIAL SOLUTIONSREQUEST A QUOTE ↗
+{% if blueprint_mode %}{% elif mode=='home' %}
STRONGER CONNECTIONS. SMARTER SOLUTIONS.

{{page.title if page.title!=site.name else 'BUILT TO LAST.'}}

{{page.summary or site.tagline or 'Industrial excellence, quality products and dependable worldwide delivery.'}}

EXPLORE PRODUCTS ↗
01 / MATERIALS02 / ENGINEERING03 / SERVICE
{% if page.cover %}{{page.title}}{% else %}
INDUSTRY
IN MOTION
{% endif %}
+{% elif mode=='notfound' %}
ERROR

404 — Page not found

+{% else %}
{{type_names.get(page.type,'COMPANY')|upper}} / {{'PRODUCT CATALOG' if mode=='listing' else 'OUR EXPERTISE'}}

{{page.title}}

{{page.summary}}

{% endif %} +{% if blueprint_mode %}
{{blocks}}
{% else %}
{% if mode=='home' %}
01PRODUCT ENGINEERING
02GLOBAL SOURCING
03QUALITY ASSURANCE
{% endif %} +{% if mode in ['home','detail'] and (content or blocks) %}
{{blocks}}{{content}}
{% endif %} +{% if mode=='detail' and page.cover %}
{{page.title}}
{% endif %} +{% set cards=listing_items if mode=='listing' else entries|selectattr('type','equalto','product')|list if mode=='home' else [] %} +{% if cards %}
OUR PORTFOLIO

{{'Product Catalogue' if mode=='listing' else 'Explore Our Products'}}

{% if mode=='home' %}ALL PRODUCTS ↗{% endif %}
{% endif %}
+{% endif %} diff --git a/themes/trade-pro/theme.css b/themes/trade-pro/theme.css new file mode 100644 index 0000000..f0150ce --- /dev/null +++ b/themes/trade-pro/theme.css @@ -0,0 +1,15 @@ +/* trade-pro design tokens (skeleton; full cms port in Phase 3) */ +:root{--sf-tp-primary:#0b3d91;--sf-tp-accent:#f5a623;--sf-tp-bg:#ffffff;--sf-tp-text:#1a2332;--sf-tp-muted:#5a6a7e;--sf-tp-radius:8px;--sf-tp-font:'Inter',system-ui,-apple-system,sans-serif} +body{margin:0;font-family:var(--sf-tp-font);color:var(--sf-tp-text);background:var(--sf-tp-bg)} +/* trade-pro buttons use the sf-tp- prefix so the platform custom.css rules + (.btn/.primary/.request/.button/.nav-btn) can never restyle them. */ +.sf-tp-btn{display:inline-block;padding:.7rem 1.4rem;border-radius:var(--sf-tp-radius);background:var(--sf-tp-primary);color:#fff;text-decoration:none;font-weight:600;border:1px solid var(--sf-tp-primary)} +.sf-tp-btn:hover{background:#0a357d} +.sf-tp-btn:focus-visible{outline:2px solid var(--sf-tp-accent);outline-offset:2px} +.sf-tp-btn-outline{background:transparent;color:var(--sf-tp-primary)} +.sf-tp-btn-outline:hover{background:#eef4fc;color:#0a357d} +/* Minimal skeleton accents so the page is not unstyled before the Phase 3 port. */ +.pro-utility{background:var(--sf-tp-primary);color:#fff} +.pro-eyebrow{color:var(--sf-tp-primary);letter-spacing:.14em} +.pro-home-hero em{color:var(--sf-tp-primary)} +a{color:var(--sf-tp-primary)} diff --git a/themes/trade-pro/versions/.gitkeep b/themes/trade-pro/versions/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/themes/trade-pro/visual/.gitkeep b/themes/trade-pro/visual/.gitkeep new file mode 100644 index 0000000..e69de29