diff --git a/tests/test_theme_registry.py b/tests/test_theme_registry.py
index efa9305..59ddff3 100644
--- a/tests/test_theme_registry.py
+++ b/tests/test_theme_registry.py
@@ -177,6 +177,37 @@ def test_theme_color_map_covers_trade_pro():
{'title': 'Home', 'route': '/'}, [], mode='home')
assert ' (subpaths allowed) so the
+ d attribute survives autoescaping without |safe. Unknown names fall
+ back to arrow-right instead of raising (page code typos must never
+ take a build down). #}
+{% set _tp_icon_paths={
+ 'arrow-right':'M5 12h14M12 5l7 7-7 7',
+ 'arrow-left':'M19 12H5M12 19l-7-7 7-7',
+ 'chevron-down':'M6 9l6 6 6-6',
+ 'check':'M20 6 9 17 4 12',
+ 'phone':'M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z',
+ 'mail':'M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2Zm18 2-10 7L2 6',
+ 'location':'M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0ZM12 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z',
+ 'download':'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3',
+ 'search':'M11 3a8 8 0 1 0 0 16 8 8 0 0 0 0-16ZM21 21l-4.35-4.35',
+ 'quote':'M8 3a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2 1 1 0 0 0-1 1v1a1 1 0 0 0 1 1 2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-2a2 2 0 0 1 2-2 1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1 2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4ZM16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a1 1 0 0 1-1 1 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2 1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1 2 2 0 0 0 2-2V5a2 2 0 0 0-2-2h-4Z'
+} %}
+{% macro icon(name, size=None, cls='') -%}
+{%- set _d=_tp_icon_paths.get(name) or _tp_icon_paths['arrow-right'] -%}
+
+{%- endmacro %}
{% macro cover(item, kind='product') %}
{% if item.cover %}
{% else %}
{{ (item.title or 'SF')[:2] }} {{ kind|upper }}
{% endif %}
@@ -9,11 +33,11 @@
{{ 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 ↗
+ {{ item.title }} {{ (item.summary or '')[:128] }}
View details {{ icon('arrow-right') }}
{% 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() %}Search Brand All brands Category All categories
{% endmacro %}
-{% macro footer_links(nav) %}{% endmacro %}
+{% macro section_title(eyebrow,heading,href='') %}{% endmacro %}
+{% macro filters() %}Search {{ icon('search') }} Brand All brands Category All categories
{% 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/pages/article.html b/themes/trade-pro/pages/article.html
index dfca60f..6983f2d 100644
--- a/themes/trade-pro/pages/article.html
+++ b/themes/trade-pro/pages/article.html
@@ -1 +1 @@
-LATEST NEWS / INSIGHTS {{page.title}} {{page.summary}}
{% if fields.get('publish_date') %}
{{fields.get('publish_date')}} {% endif %}
{% if page.cover %} {% endif %}{{body_copy(content,page)}}← Back to news
+LATEST NEWS / INSIGHTS {{page.title}} {{page.summary}}
{% if fields.get('publish_date') %}
{{fields.get('publish_date')}} {% endif %}
{% if page.cover %} {% endif %}{{body_copy(content,page)}}{{ icon('arrow-left') }} Back to news
diff --git a/themes/trade-pro/pages/case.html b/themes/trade-pro/pages/case.html
index 7c16d86..8ae8407 100644
--- a/themes/trade-pro/pages/case.html
+++ b/themes/trade-pro/pages/case.html
@@ -1 +1 @@
-SELECTED WORK / PROJECT {{page.title}} {{page.summary}}
{% if page.cover %}
{% 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 →
+SELECTED WORK / PROJECT {{page.title}} {{page.summary}}
{% if page.cover %}
{% 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 {{ icon('arrow-right') }}
diff --git a/themes/trade-pro/pages/category.html b/themes/trade-pro/pages/category.html
index 8b2ea73..57e1a27 100644
--- a/themes/trade-pro/pages/category.html
+++ b/themes/trade-pro/pages/category.html
@@ -1,2 +1,2 @@
DISCOVER / {{'CATEGORY' if kind=='category' else 'COLLECTION'}} {{page.title}} {{page.summary or 'Browse all published content in this section.'}}
-{{ filters() }}
{{grid(listing,'catalog')}}
{% if pagination and pagination.pages>1 %}
{% if pagination.previous %}← Previous {% endif %}Page {{pagination.page}} of {{pagination.pages}} {% if pagination.next %}Next → {% endif %} {% endif %}
+
diff --git a/themes/trade-pro/pages/contact.html b/themes/trade-pro/pages/contact.html
index b4ef08b..07cf572 100644
--- a/themes/trade-pro/pages/contact.html
+++ b/themes/trade-pro/pages/contact.html
@@ -1,6 +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 %}
{% endif %}
+{{body_copy(content,page)}}{% if page.cover %}
{% endif %}
{% if form_endpoint %}
CONTACT FORM Send a business enquiry Submissions go directly to the external form service configured by the site administrator.
-
+Name Email Message Submit enquiry {{ icon('arrow-right') }} Form submissions are handled by the external service; review its privacy and spam-filtering settings.
{% endif %}
diff --git a/themes/trade-pro/pages/home.html b/themes/trade-pro/pages/home.html
index dc522a6..b44299c 100644
--- a/themes/trade-pro/pages/home.html
+++ b/themes/trade-pro/pages/home.html
@@ -2,7 +2,7 @@
industrial on purpose: the 4-family distinct-markup tripwire in
test_theme_pro_v3 counts distinct pro-home-hero class strings, and the
Phase 3 visual port will give trade-pro its own hero variant. -->
-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 %}
{% else %}
{% endif %}
-{% if categories %}{{section_title('PRODUCT CATEGORIES','Shop by category','/products/')}}
{% endif %}
+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 %}
{% else %}
{% endif %}
+{% if categories %}{{section_title('PRODUCT CATEGORIES','Shop by category','/products/')}}
{% endif %}
{{section_title('TRADE CATALOGUE','Featured products','/products/')}}{{grid(showcase,'product')}}
-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
index 8b2ea73..57e1a27 100644
--- a/themes/trade-pro/pages/listing.html
+++ b/themes/trade-pro/pages/listing.html
@@ -1,2 +1,2 @@
DISCOVER / {{'CATEGORY' if kind=='category' else 'COLLECTION'}} {{page.title}} {{page.summary or 'Browse all published content in this section.'}}
-{{ filters() }}
{{grid(listing,'catalog')}}
{% if pagination and pagination.pages>1 %}
{% if pagination.previous %}← Previous {% endif %}Page {{pagination.page}} of {{pagination.pages}} {% if pagination.next %}Next → {% endif %} {% endif %}
+
diff --git a/themes/trade-pro/pages/notfound.html b/themes/trade-pro/pages/notfound.html
index abf2674..cf49837 100644
--- a/themes/trade-pro/pages/notfound.html
+++ b/themes/trade-pro/pages/notfound.html
@@ -1 +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
index d8c451a..d490316 100644
--- a/themes/trade-pro/pages/product.html
+++ b/themes/trade-pro/pages/product.html
@@ -1,3 +1,3 @@
-
{{cover(page,'product')}}
{% if gallery|length>1 %}
{% for photo in gallery %}
{% endfor %}
{% endif %}
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 ↗
+
{{cover(page,'product')}}
{% if gallery|length>1 %}
{% for photo in gallery %}
{% endfor %}
{% endif %}
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 {{ icon('arrow-right') }}
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/pro.html b/themes/trade-pro/pro.html
index dc63541..a8e6081 100644
--- a/themes/trade-pro/pro.html
+++ b/themes/trade-pro/pro.html
@@ -1,5 +1,5 @@
{{ seo_title }} {% if canonical %} {% endif %} {% 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 %}
+{% from '_professional_components.html' import card,cover,grid,section_title,filters,footer_links,body_copy,icon 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
@@ -16,10 +16,10 @@
keeping all 7 default sections so only the labels change, never coverage. #}
{% set tp_nav=[{'title':'Home','route':'/'},{'title':'Products','route':'/products/'},{'title':'Brands','route':'/brands/'},{'title':'News','route':'/news/'},{'title':'Cases','route':'/cases/'},{'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 · DELIVERY INTERNATIONAL B2B SOLUTIONS
{% 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 %}
+{% if kind not in ('notfound','search') %}{% endif %}
diff --git a/themes/trade-pro/site.html b/themes/trade-pro/site.html
index 630bab5..48ba525 100644
--- a/themes/trade-pro/site.html
+++ b/themes/trade-pro/site.html
@@ -1,12 +1,19 @@
{{seo_title}} {% if canonical %} {% endif %}
+{# site.html renders in environments where the trade-pro macro library cannot
+ be imported (theme-package previews load only the package dir), so its arrow
+ is a self-contained copy of the icon macro's arrow-right glyph. Same style
+ contract: 24×24 viewBox, currentColor stroke, decorative aria-hidden. #}
+{% macro tp_arrow() -%}
+
+{%- endmacro %}
ENGINEERING · MANUFACTURING · SUPPLY GLOBAL INDUSTRIAL SOLUTIONS
-
-{% 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 / MATERIALS 02 / ENGINEERING 03 / SERVICE
{% if page.cover %}
{% else %}
INDUSTRY IN MOTION {% endif %}
+
+{% 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 {{ tp_arrow() }} 01 / MATERIALS 02 / ENGINEERING 03 / SERVICE
{% if page.cover %}
{% 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' %}01 PRODUCT ENGINEERING
02 GLOBAL SOURCING
03 QUALITY ASSURANCE
{% endif %}
{% if mode in ['home','detail'] and (content or blocks) %}{{blocks}}{{content}} {% endif %}
{% if mode=='detail' and page.cover %} {% 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 %}
+{% if cards %}{% endif %}
{% endif %}
diff --git a/themes/trade-pro/theme.css b/themes/trade-pro/theme.css
index 373dc39..d2631a4 100644
--- a/themes/trade-pro/theme.css
+++ b/themes/trade-pro/theme.css
@@ -585,6 +585,47 @@ body.sf-theme-trade-pro {
margin: 0;
}
+/* ── 图标(Task 9 SVG 宏库:内联线条图标的对齐与间距)── */
+
+/* 基线对齐:inline 上下文垂直居中,flex 上下文不被压缩换行 */
+.sf-tp-icon {
+ display: inline-block;
+ vertical-align: middle;
+ flex-shrink: 0;
+}
+
+/* 按钮内紧跟文字的图标留出呼吸空间(flex gap 之外的显式间距,
+ 兼容图标包在 里或直接暴露两种写法) */
+.sf-tp-btn svg {
+ margin-inline-start: var(--sf-tp-space-1);
+}
+
+/* 非按钮内联上下文:图标贴着文字时补一点间距 */
+.pro-mega a .sf-tp-icon,
+.pro-contact-email .sf-tp-icon,
+.pro-footer-links a .sf-tp-icon {
+ margin-inline-start: var(--sf-tp-space-1);
+}
+
+/* filters 宏搜索框:放大镜占位在输入框内左侧(不抢焦点) */
+.sf-theme-trade-pro .pro-filter-search-box {
+ position: relative;
+ display: block;
+ margin: 0; /* 抵消 pro-base 的 label>span 说明文字样式 */
+}
+
+.sf-theme-trade-pro .pro-filter-search-box .sf-tp-icon {
+ position: absolute;
+ inset-inline-start: var(--sf-tp-space-3);
+ inset-block-end: var(--sf-tp-space-3);
+ pointer-events: none;
+ color: var(--sf-tp-color-text-muted);
+}
+
+.sf-theme-trade-pro .pro-filter-search-box input {
+ padding-inline-start: calc(var(--sf-tp-icon-size-md, 20px) + var(--sf-tp-space-6));
+}
+
/* ── Phase 2 桥接:骨架期 .pro-* 强调样式改由 cms 令牌驱动(Task 10 布局移植后由组件样式接管)── */
.pro-utility {