diff --git a/tests/test_theme_registry.py b/tests/test_theme_registry.py index 9fc266e..1ca5cf9 100644 --- a/tests/test_theme_registry.py +++ b/tests/test_theme_registry.py @@ -798,6 +798,112 @@ 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_chrome_layout(factory): + # Task 10j:cms 页眉/页脚 chrome 视觉还原 + 手机端抽屉导航。 + # 设计源 D:/project/cms/runtimes/astro-site-runtime/src/components/ + # Header.astro(玻璃吸顶 + 右对齐半粗导航 + 悬停下划线/下拉卡 + 移动 + # 右滑抽屉)/ Footer.astro(深色四栏 + 版权条),10j 以纯样式层把平台 + # chrome DOM(sf-site-head/pro-header/pro-navigation/pro-footer)重塑为 + # cms 设计——平台数据流(site_design 导航/公告/CTA/页脚选项)与 pro.js + # 交互钩子(data-pro-menu/data-pro-catalog/data-pro-mega/pro-nav-disclose) + # 全部保留。抽屉复用上游 V8.21.3 四主题机制(commercial.css 样式段 + + # pro.js 通用逻辑:选择器寻钩子而非主题分支,trade-pro 输出同款类名 + # 结构即自动可用);mobile_tabs 为模板驱动,10j 给 trade-pro 补上 + # 渲染块后配置即生效(下方发布前后双构建断言)。 + import re + sid = site(factory) + assert factory.post(f'/api/factory/sites/{sid}/bootstrap').status_code == 200 + 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'] + html = factory.get(f'/preview/{sid}/{bid}/').text + soup = BeautifulSoup(html, 'html.parser') + # ── 平台 chrome 结构与交互钩子保留(数据流不破坏的结构证据)── + header = soup.select_one('header.sf-site-head.pro-header') + assert header is not None + assert header.select_one('.pro-wrap.pro-head-inner') is not None + assert header.select_one('a.pro-logo[href$="/"]') is not None # /preview/ 重写根相对 href,用后缀匹配 + toggle = header.select_one('button.pro-mobile-toggle[data-pro-menu]') + assert toggle is not None and toggle.get('aria-controls') == 'pro-navigation' + nav = header.select_one('nav#pro-navigation.pro-navigation') + assert nav is not None and nav.get('aria-label') + # catalog/mega 钩子(aria-controls 对应 mega 面板 id;面板本体按 categories 条件渲染) + catalog = header.select_one('button.pro-catalog-toggle[data-pro-catalog]') + assert catalog is not None and catalog.get('aria-controls') == 'pro-mega-content' + # CTA 双挂 sf-tp-btn(cms 蓝按钮形态)+ chrome.header CTA 数据位 + cta = header.select_one('a.pro-header-cta.sf-tp-btn') + assert cta is not None and cta.get('href', '').endswith('/contact/') + # 公告条数据位仍在(未发布 site_design 时渲染英文兜底文案) + assert soup.select_one('.pro-utility .pro-wrap') is not None + # ── 英文兜底导航(tp_nav):7 项默认栏目全渲染(尾部可跟 Search 链接—— + # chrome.header.show_search 数据位默认开)── + nav_links = nav.select(':scope > a, :scope > .pro-nav-group > a') + nav_text = [a.get_text(strip=True) for a in nav_links] + assert nav_text[:7] == ['Home', 'Products', 'Brands', 'News', 'Cases', 'About', 'Contact'] + assert nav_text[7:] in ([], ['Search']) + # ── 页脚:平台 DOM + cms 栏目标题(Quick Links 随 footer_nav 数据流) + footer = soup.select_one('footer.sf-site-foot.pro-footer') + assert footer is not None + assert footer.select_one('.pro-footer-top') is not None + heading = footer.select_one('.pro-footer-links h3') + assert heading is not None and heading.get_text(strip=True) == 'Quick Links' + footer_nav = footer.select('.pro-footer-links ul li a') + assert len(footer_nav) == 7 and footer_nav[0].get_text(strip=True) == 'Home' + assert footer.select_one('.pro-footer-bottom') is not None + # ── 10j 视觉层随构建分发(pro.css:cms chrome 映射的样式证据)── + pro_css = factory.get(f'/preview/{sid}/{bid}/assets/pro.css').text + assert 'Task 10j' in pro_css + # 玻璃拟态吸顶(Header.astro .site-header) + assert re.search(r'\.sf-theme-trade-pro \.pro-header\{[^}]*position:sticky', pro_css) + assert 'backdrop-filter:blur(10px)' in pro_css + # 导航:cms 右对齐半粗 + 悬停下划线(.nav-links a 的 border-block-end 方案) + assert re.search(r'\.sf-theme-trade-pro \.pro-navigation \.pro-nav-group>a[^{]*\{[^}]*border-block-end', pro_css) + assert 'var(--sf-tp-color-border-brand)' in pro_css + # 下拉卡(.sub-menu):白卡 + 发丝边 + radius-sm + shadow-md 的令牌引用 + assert re.search(r'\.sf-theme-trade-pro \.pro-nav-children\{[^}]*var\(--sf-tp-color-surface-default\)', pro_css) + # 深色页脚(.site-footer 令牌桥:surface-inverse + 版权条 border-inverse) + assert re.search(r'\.sf-theme-trade-pro \.pro-footer\{[^}]*var\(--sf-tp-color-surface-inverse\)', pro_css) + assert 'var(--sf-tp-color-border-inverse)' in pro_css + # 抽屉品牌化变量桥:平台 drawer 样式段消费 --pro-* 变量,10j 注入 cms 令牌 + assert '--pro-background:var(--sf-tp-color-surface-default)' in pro_css + # ── 上游抽屉机制复用(commercial.css/pro.js 随构建分发 + 安全区适配)── + assert 'assets/commercial.css' in html and 'assets/pro.js' in html + commercial = factory.get(f'/preview/{sid}/{bid}/assets/commercial.css').text + assert '.sf-mobile-drawer-backdrop' in commercial and 'sf-drawer-open' in commercial + assert 'env(safe-area-inset-bottom' in commercial # 抽屉/底部 tabs 的安全区适配 + pro_js = factory.get(f'/preview/{sid}/{bid}/assets/pro.js').text + assert 'sf-drawer-header' in pro_js and 'sf-drawer-extra' in pro_js and 'Escape' in pro_js + # ── mobile_tabs:发布 site_design 前不渲染,发布后渲染(含 menu 动作开抽屉)── + assert 'data-mobile-tabs' not in html + import copy + from app import site_design_v87 + config = copy.deepcopy(site_design_v87.DEFAULTS) + config['mobile_tabs'] = {'enabled': True, 'items': [ + {'title': 'Home', 'icon': 'home', 'route': '/', 'action': 'link'}, + {'title': 'Products', 'icon': 'products', 'route': '/products/', 'action': 'link'}, + {'title': 'Menu', 'icon': 'menu', 'route': '/', 'action': 'menu'}]} + url = f'/api/sites/{sid}/site-design' + assert factory.put(url, json={'config': config, 'expected_revision': 0}).status_code == 200 + assert factory.post(url + '/publish', json={'expected_revision': 1}).status_code == 200 + bid2 = factory.post(f'/api/sites/{sid}/builds', json={}).json()['version'] + html2 = factory.get(f'/preview/{sid}/{bid2}/').text + assert 'data-mobile-tabs' in html2 and 'data-mobile-open-menu' in html2 + tabs = BeautifulSoup(html2, 'html.parser').select('.sf-mobile-tabs .sf-mobile-tab') + assert len(tabs) == 3 + assert [t.select_one('.sf-tab-label').get_text(strip=True) for t in tabs] == ['Home', 'Products', 'Menu'] + assert tabs[0].select_one('.sf-tab-icon') is not None # 图标位渲染 + # 发布后 chrome_is_custom 生效:公告条走配置数据位(announcement 文案 + + # show_announcement 开关)。publish 会清空草稿 → 新 PUT 从 revision 0 重新开始 + announced = {**config, 'header': {**config['header'], 'announcement': 'Global sourcing update', 'show_announcement': True}} + assert factory.put(url, json={'config': announced, 'expected_revision': 0}).status_code == 200 + assert factory.post(url + '/publish', json={'expected_revision': 1}).status_code == 200 + bid3 = factory.post(f'/api/sites/{sid}/builds', json={}).json()['version'] + html3 = factory.get(f'/preview/{sid}/{bid3}/').text + assert 'Global sourcing update' in html3 + # 本构建链接全通(chrome 改动不产生断链) + report = factory.get(f'/api/sites/{sid}/builds/{bid3}/report').json() + assert not report['errors'] and not report['broken_links'] + + def test_frontend_entries_include_trade_pro(): from pathlib import Path base = Path(__file__).resolve().parent.parent diff --git a/themes/trade-pro/pro.css b/themes/trade-pro/pro.css index 9616bbd..f1b37bf 100644 --- a/themes/trade-pro/pro.css +++ b/themes/trade-pro/pro.css @@ -589,3 +589,159 @@ -body-section 仅作模板定位钩子,无视觉规则;响应式(767/620 hero 竖版 与正文紧凑字号)全部由 10c/10d 既有媒体块经共用类名覆盖——无自有媒体块 即无级联顺序风险(10c 教训:同特异性按源顺序取胜)。 #} + +/* ── Task 10j:cms 页眉/页脚 chrome 视觉还原 + 手机端抽屉导航 ── + 源 src/components/Header.astro(玻璃拟态吸顶:brand-soft 88% + blur(10px)、 + 右对齐半粗导航 + 透明下划线悬停转品牌线、白卡下拉(hover/键盘聚焦展开)、 + 汉堡 + 右滑抽屉 + 遮罩)与 Footer.astro(surface-inverse 深底四栏栅格 + + h3 栏目标题 + 发丝线版权条),像素基准 dist/hesupipe/en/。 + 纯样式层重塑平台 chrome DOM(.pro-utility/.pro-header/.pro-head-inner/ + .pro-navigation/.pro-nav-children/.pro-mega/.pro-footer 等),数据流与 + pro.js 钩子全保留。机制复用说明: + - 抽屉 = 上游 V8.21.3 四主题统一机制(commercial.css 的 ≤1024px 样式段 + + pro.js 通用逻辑按 [data-pro-menu]/#pro-navigation 选择器寻钩子,与主题 + 无关);trade-pro 的 pro.html 本就输出同款类名结构,机制自动可用。 + - 平台 drawer/tabs 样式段消费 --pro-* 变量且大量 !important 锁定(宽度/ + 定位/内边距/链接色等),本块以 .sf-theme-trade-pro 作用域的变量桥把 + cms 令牌注入 --pro-*(body 级声明压过 pro-base 的 :root,继承取胜, + 零 !important 对抗)——抽屉/底部 tabs/下拉卡的配色随桥整体品牌化。 + - mobile_tabs 为模板驱动(pro.html 渲染块 + commercial.css 767px 样式 + + pro.js [data-mobile-open-menu] 开抽屉),10j 给 trade-pro 补上渲染块。 + 级联:本块 0,2,0+ 作用域规则晚于 pro-base/commercial(链接序 theme → + blocks → factory → pro-base → pro → commercial)与本文件 Phase 2 tint + 层;对 commercial 中同特异性晚载规则(如 .pro-end-cta h2、 + .pro-header-cta:hover)以更高特异性取胜,不用 !important。 */ + +/* 变量桥:平台 chrome(含 commercial 抽屉/底部 tabs 的 !important 锁定段) + 全部经 --pro-* 消费颜色 → cms 令牌直通(含焦点环/激活 tab 色) */ +.sf-theme-trade-pro{--pro-background:var(--sf-tp-color-surface-default);--pro-surface:var(--sf-tp-color-surface-muted);--pro-border:var(--sf-tp-color-border-subtle);--pro-text:var(--sf-tp-color-text-primary);--pro-muted:var(--sf-tp-color-text-muted);--pro-accent:var(--sf-tp-color-brand-primary);--pro-hero:var(--sf-tp-color-surface-inverse);--pro-radius:var(--sf-tp-radius-sm)} + +/* chrome 容器 = cms .wrap 几何(min(1440px,90vw),无内边距靠宽度收边); + 页面内容模板已用 .wrap 同款(10a-10h),页眉/页脚自此与正文对齐。 + 620 的 mobile_container_padding 配置项被下方 620 块的 cms 几何覆盖 + (等价意图:宽度收边),其余 site_design 选项(导航/公告/CTA/页脚/ + mobile_tabs)不受影响 */ +.sf-theme-trade-pro .pro-wrap{width:min(1440px,90vw);max-width:none;padding:0;margin-inline:auto} +/* mega 例外:面板收在页面容器内(cms 下拉卡语义,非全幅横幅) */ +.sf-theme-trade-pro .pro-mega.pro-wrap{width:min(100%,var(--sf-tp-container-page-max))} + +/* 公告条(chrome.header.announcement 数据位):cms 无对应物——按 cms 深色 + 版权条语汇收敛为藏青细条(宽字距小字) */ +.sf-theme-trade-pro .pro-utility{background:var(--sf-tp-color-surface-inverse);color:var(--sf-tp-color-text-inverse-muted);font-size:var(--sf-tp-font-size-xs);letter-spacing:var(--sf-tp-letter-spacing-wide)} +.sf-theme-trade-pro .pro-utility .pro-wrap{padding-block:var(--sf-tp-space-2)} + +/* 页眉(Header.astro .site-header):sticky 玻璃拟态,cms 无底边线。 + body 的 overflow-x:hidden 会禁用后代 sticky(滚动容器劫持)——theme.css + 的 body.sf-theme-trade-pro(0,1,1) 载于本文件之前,此处同特异性晚载以 + clip 覆写(支持 clip 的浏览器内 sticky 生效,不支持则回落现状) */ +body.sf-theme-trade-pro{overflow-x:hidden;overflow-x:clip} +.sf-theme-trade-pro .pro-header{position:sticky;top:0;z-index:var(--sf-tp-z-sticky);background:color-mix(in srgb,var(--sf-tp-color-surface-brand-soft) 88%,transparent);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-block-end:0} +.sf-theme-trade-pro .pro-head-inner{min-height:var(--sf-tp-space-16);gap:var(--sf-tp-space-8)} +/* Logo(cms .logo-img:高 44px 宽自适应;max-width 兜底防超宽图溢出) */ +.sf-theme-trade-pro .pro-logo{min-width:0} +.sf-theme-trade-pro .pro-brand-logo{height:calc(var(--sf-tp-space-10) + var(--sf-tp-space-1));width:auto;max-width:min(30vw,220px);max-height:none;object-fit:contain} +.sf-theme-trade-pro .pro-logo-name{font-size:var(--sf-tp-font-size-lg);font-weight:var(--sf-tp-font-weight-semibold);letter-spacing:var(--sf-tp-letter-spacing-tight)} +.sf-theme-trade-pro .pro-logo-name small{color:var(--sf-tp-color-text-muted)} + +/* 导航(cms .nav-links):右对齐(pro-base margin-left:auto 保留)、半粗、 + 拉伸满高、透明下划线悬停转品牌色实线(cms active 态的平台化——静态 + 产物无当前页标记,悬停即反馈);搜索链接(show_search 数据位)并入导航 + 字级,pro-base 的 19px!important 需同强度覆写 */ +.sf-theme-trade-pro .pro-navigation{gap:var(--sf-tp-space-8);align-self:stretch;align-items:stretch} +.sf-theme-trade-pro .pro-navigation>a,.sf-theme-trade-pro .pro-navigation .pro-nav-group>a{display:flex;align-items:center;color:var(--sf-tp-color-text-primary);font-size:var(--sf-tp-font-size-md);font-weight:var(--sf-tp-font-weight-semibold);border-block-end:var(--sf-tp-border-width-medium) solid transparent;transition:color var(--sf-tp-duration-fast) var(--sf-tp-easing-standard),border-color var(--sf-tp-duration-fast) var(--sf-tp-easing-standard)} +.sf-theme-trade-pro .pro-navigation>a:hover,.sf-theme-trade-pro .pro-navigation .pro-nav-group>a:hover{color:var(--sf-tp-color-text-link);border-block-end-color:var(--sf-tp-color-border-brand);opacity:1} +.sf-theme-trade-pro .pro-search-link{font-size:var(--sf-tp-font-size-sm)!important;color:var(--sf-tp-color-text-secondary);gap:var(--sf-tp-space-1)} + +/* caret(cms .caret ▾ 旋转 180°):disclose 钮去按钮化,随组悬停/展开旋转 */ +.sf-theme-trade-pro .pro-navigation .pro-nav-disclose{padding:var(--sf-tp-space-2);color:var(--sf-tp-color-text-muted);align-self:center} +.sf-theme-trade-pro .pro-navigation .pro-nav-disclose .sf-tp-icon{transition:transform var(--sf-tp-duration-fast) var(--sf-tp-easing-standard)} +.sf-theme-trade-pro .pro-navigation .pro-nav-group:hover .pro-nav-disclose .sf-tp-icon,.sf-theme-trade-pro .pro-navigation .pro-nav-disclose[aria-expanded="true"] .sf-tp-icon{transform:rotate(180deg)} + +/* CTA(chrome.header.show_cta 数据位):cms 按钮语汇(蓝底白字、radius 10px、 + 悬浮上抬 + shadow-sm);commercial 的 .pro-header-cta:hover(0,2,0) 晚载 + ——以 0,3,0 取胜 */ +.sf-theme-trade-pro .pro-header-cta{min-height:calc(var(--sf-tp-button-height-md) - var(--sf-tp-space-1));padding-inline:var(--sf-tp-button-padding-x-sm);font-size:var(--sf-tp-font-size-sm);font-weight:var(--sf-tp-button-font-weight);border-radius:var(--sf-tp-button-border-radius);background:var(--sf-tp-color-surface-brand);border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-brand);color:var(--sf-tp-color-text-on-brand)} +.sf-theme-trade-pro .pro-header-cta:hover{transform:translateY(calc(-1 * var(--sf-tp-space-1)));background:var(--sf-tp-color-brand-primary-strong);box-shadow:var(--sf-tp-shadow-sm);color:var(--sf-tp-color-text-on-brand)} + +/* 下拉卡(cms .sub-menu):白卡 + 发丝边 + radius-sm + shadow-md + 小字链接 + brand-soft 悬停(叶子项缩进灰字) */ +.sf-theme-trade-pro .pro-nav-children{min-width:220px;padding:var(--sf-tp-space-2);display:grid;gap:var(--sf-tp-space-1);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-radius-sm);box-shadow:var(--sf-tp-shadow-md)} +.sf-theme-trade-pro .pro-nav-children a{padding:var(--sf-tp-space-2) var(--sf-tp-space-3);font-size:var(--sf-tp-font-size-sm);font-weight:var(--sf-tp-font-weight-medium);color:var(--sf-tp-color-text-secondary);border-radius:var(--sf-tp-radius-xs);white-space:normal} +.sf-theme-trade-pro .pro-nav-children a:hover{background:var(--sf-tp-color-surface-brand-soft);color:var(--sf-tp-color-text-link)} +.sf-theme-trade-pro .pro-nav-children .pro-nav-leaf{padding-inline-start:var(--sf-tp-space-6);color:var(--sf-tp-color-text-muted)} + +/* mega 面板(data-pro-mega 钩子保留;cms 无对应物——产品分类条按下拉卡 + 语汇收敛:去下划线列表改 brand-soft 悬停) */ +.sf-theme-trade-pro .pro-mega{padding:var(--sf-tp-space-5);border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-subtle);border-radius:0 0 var(--sf-tp-radius-sm) var(--sf-tp-radius-sm);box-shadow:var(--sf-tp-shadow-md)} +.sf-theme-trade-pro .pro-mega>span{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 .pro-mega>div a{font-size:var(--sf-tp-font-size-sm);font-weight:var(--sf-tp-font-weight-medium);color:var(--sf-tp-color-text-secondary);border-block-end:0;border-radius:var(--sf-tp-radius-xs);transition:background-color var(--sf-tp-duration-fast) var(--sf-tp-easing-standard),color var(--sf-tp-duration-fast) var(--sf-tp-easing-standard)} +.sf-theme-trade-pro .pro-mega>div a:hover{background:var(--sf-tp-color-surface-brand-soft);color:var(--sf-tp-color-text-link)} +.sf-theme-trade-pro .pro-mega>div a .sf-tp-icon{color:var(--sf-tp-color-text-muted)} + +/* 汉堡(cms .drawer-toggle 三线形态):44px 触达目标保留(commercial 锁定), + ☰ 字形以三道 2px 线替代(font-size:0 隐字,纯视觉层;桌面本就 display:none) */ +.sf-theme-trade-pro .pro-mobile-toggle{font-size:0;color:var(--sf-tp-color-text-primary);border:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-default);border-radius:var(--sf-tp-radius-xs);background:linear-gradient(var(--sf-tp-color-text-primary),var(--sf-tp-color-text-primary)) center top 12px/18px 2px no-repeat,linear-gradient(var(--sf-tp-color-text-primary),var(--sf-tp-color-text-primary)) center/18px 2px no-repeat,linear-gradient(var(--sf-tp-color-text-primary),var(--sf-tp-color-text-primary)) center bottom 12px/18px 2px no-repeat} + +/* 页脚(Footer.astro .site-footer):surface-inverse 深底 + 栏目栅格(cms + 1.7/0.8/0.9/1.25 四栏 → 平台三栏 DOM 映射为 1.7/0.9/1.25)+ h3 栏目 + 标题(Quick Links 随 footer_nav 数据流)+ 发丝线版权条 */ +.sf-theme-trade-pro .pro-footer{background:var(--sf-tp-color-surface-inverse);color:var(--sf-tp-color-text-inverse-muted);padding:calc(var(--sf-tp-space-12) + var(--sf-tp-space-4)) 0 var(--sf-tp-space-5)} +.sf-theme-trade-pro .pro-footer-top{display:grid;grid-template-columns:1.7fr 0.9fr 1.25fr;gap:calc(var(--sf-tp-space-12) + var(--sf-tp-space-4))} +.sf-theme-trade-pro .pro-footer .pro-eyebrow{color:var(--sf-tp-color-text-inverse-muted)} +.sf-theme-trade-pro .pro-footer h2{font-size:var(--sf-tp-font-size-xl);font-weight:var(--sf-tp-font-weight-bold);letter-spacing:var(--sf-tp-letter-spacing-tight);color:var(--sf-tp-color-text-inverse);margin-block-end:var(--sf-tp-space-3)} +.sf-theme-trade-pro .pro-footer h3{font-size:var(--sf-tp-font-size-md);color:var(--sf-tp-color-text-inverse);margin-block-end:var(--sf-tp-space-3)} +.sf-theme-trade-pro .pro-footer p{font-size:var(--sf-tp-font-size-sm);color:var(--sf-tp-color-text-inverse-muted);margin:0 0 var(--sf-tp-space-2)} +.sf-theme-trade-pro .pro-footer a{color:var(--sf-tp-color-text-inverse-muted)} +.sf-theme-trade-pro .pro-footer a:hover{color:var(--sf-tp-color-text-inverse)} +.sf-theme-trade-pro .pro-footer-links ul{display:flex;flex-direction:column;gap:var(--sf-tp-space-1);margin:0;padding:0;list-style:none} +.sf-theme-trade-pro .pro-footer-links a{font-size:var(--sf-tp-font-size-sm);padding-block:var(--sf-tp-space-1)} +/* cms 页脚链接为纯文字(无箭头)——装饰性 SVG 隐藏,DOM 保留 */ +.sf-theme-trade-pro .pro-footer-links a .sf-tp-icon{display:none} +.sf-theme-trade-pro .pro-footer-bottom{border-block-start:var(--sf-tp-border-width-hairline) solid var(--sf-tp-color-border-inverse);margin-block-start:var(--sf-tp-space-8);padding-block-start:var(--sf-tp-space-5);font-size:var(--sf-tp-font-size-xs);letter-spacing:normal;color:var(--sf-tp-color-neutral-400)} + +/* 结尾 CTA 带(pro.html 全局 pro-end-cta):与 10a sf-tp-cta 同款深色渐变 + 语汇(cms Cta 组件),白底按钮反色 */ +.sf-theme-trade-pro .pro-end-cta{background:linear-gradient(90deg,color-mix(in srgb,var(--sf-tp-color-surface-inverse) 94%,transparent),color-mix(in srgb,var(--sf-tp-color-brand-primary) 67%,transparent));color:var(--sf-tp-color-text-inverse);padding-block:calc(var(--sf-tp-space-12) + var(--sf-tp-space-4))} +.sf-theme-trade-pro .pro-end-cta .pro-eyebrow{color:var(--sf-tp-color-text-inverse-muted)} +.sf-theme-trade-pro .pro-end-cta h2{font-size:clamp(30px,4vw,var(--sf-tp-font-size-4xl));color:var(--sf-tp-color-text-inverse);letter-spacing:var(--sf-tp-letter-spacing-tight)} +.sf-theme-trade-pro .pro-end-cta p{color:color-mix(in srgb,var(--sf-tp-color-text-inverse) 83%,transparent)} +.sf-theme-trade-pro .pro-end-cta .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 .pro-end-cta .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)} + +/* 桌面下拉悬停/键盘聚焦展开(cms sub-menu 交互的纯 CSS 复刻)。仅 ≥1025px: + ≤1024 走抽屉,[hidden]=display:none 的折叠语义由 commercial !important + 锁定保留。[hidden] 面板改为 opacity/visibility 隐藏后随组悬停浮现; + pro.js 点击 disclose 置 hidden=false 仍是持久展开——两通道共存互不破坏 */ +@media (min-width:1025px){ + .sf-theme-trade-pro .pro-navigation .pro-nav-children[hidden]{display:grid!important;opacity:0;visibility:hidden;pointer-events:none;transform:translateY(var(--sf-tp-space-1));transition:opacity var(--sf-tp-duration-fast) var(--sf-tp-easing-standard),transform var(--sf-tp-duration-fast) var(--sf-tp-easing-standard),visibility var(--sf-tp-duration-fast)} + .sf-theme-trade-pro .pro-navigation .pro-nav-group:hover>.pro-nav-children,.sf-theme-trade-pro .pro-navigation .pro-nav-group:focus-within>.pro-nav-children{opacity:1;visibility:visible;pointer-events:auto;transform:translateY(0)} +} + +/* 抽屉/移动端精修(≤1024;形态与尺寸由 commercial !important 锁定段提供—— + 右滑面板 min(88vw,360px)/100dvh/安全区 padding、遮罩、sticky 抽屉头、 + 44px 触达、焦点环与 sf-drawer-extra 均为上游机制)。本块只做 cms 语汇的 + 未锁定属性:cms 头部 ≤1023 的 68px 头高/32px logo、链接悬停 brand-soft、 + 抽屉列表紧凑节奏(gap 归零靠链接自身 padding 分隔) */ +@media (max-width:1024px){ + .sf-theme-trade-pro .pro-head-inner{min-height:68px;gap:var(--sf-tp-space-4)} + .sf-theme-trade-pro .pro-brand-logo{height:var(--sf-tp-space-8)} + .sf-theme-trade-pro .pro-navigation{gap:0} + .sf-theme-trade-pro .pro-navigation>a:hover,.sf-theme-trade-pro .pro-navigation .pro-nav-group>a:hover,.sf-theme-trade-pro .pro-navigation .sf-drawer-extra>a:hover{background:var(--sf-tp-color-surface-brand-soft)} + .sf-theme-trade-pro .sf-drawer-header{font-size:var(--sf-tp-font-size-md);font-weight:var(--sf-tp-font-weight-semibold);letter-spacing:var(--sf-tp-letter-spacing-normal)} +} + +/* chrome 响应式(cms 断点):1280 导航降一档字级防溢出;900 页脚折两栏 + (联系栏整行,cms Footer 900 同构);620 单栏 + 版权条堆叠 + wrap 收边 + (cms .wrap 620 = calc(100% - 30px)) */ +@media (max-width:1280px){ + .sf-theme-trade-pro .pro-navigation>a,.sf-theme-trade-pro .pro-navigation .pro-nav-group>a{font-size:var(--sf-tp-font-size-sm)} +} +@media (max-width:900px){ + .sf-theme-trade-pro .pro-footer-top{grid-template-columns:1.5fr 1fr;gap:var(--sf-tp-space-10)} + .sf-theme-trade-pro .pro-footer-top>div:last-child{grid-column:1/-1} +} +@media (max-width:620px){ + .sf-theme-trade-pro .pro-wrap{width:calc(100% - 30px)} + .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} +} diff --git a/themes/trade-pro/pro.html b/themes/trade-pro/pro.html index b721112..1654dd2 100644 --- a/themes/trade-pro/pro.html +++ b/themes/trade-pro/pro.html @@ -21,7 +21,9 @@ {% 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 {{ icon('arrow-right') }}
{% endif %} - + +{% if chrome.mobile_tabs['enabled'] and chrome.mobile_tabs['items'] %}{% endif %}