diff --git a/web-pages/product-site/assets/css/site.css b/web-pages/product-site/assets/css/site.css index f104bab93..d322a787d 100644 --- a/web-pages/product-site/assets/css/site.css +++ b/web-pages/product-site/assets/css/site.css @@ -352,6 +352,56 @@ img { max-width: 900px; } +.repository-router-links { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 28px; +} + +.repository-router-links a { + display: grid; + grid-template-columns: 1fr auto; + gap: 6px 16px; + min-height: 112px; + padding: 18px 0 0; + border-top: 3px solid var(--green); + color: inherit; + text-decoration: none; +} + +.repository-router-links a:nth-child(2) { + border-color: #d08a21; +} + +.repository-router-links a:nth-child(3) { + border-color: #d84b55; +} + +.repository-router-links span { + color: var(--muted); + font-size: 13px; + font-weight: 750; +} + +.repository-router-links strong { + font-size: 18px; + line-height: 1.35; +} + +.repository-router-links img { + grid-column: 2; + grid-row: 1 / span 2; + width: 20px; + height: 20px; + align-self: center; + transition: transform 160ms ease; +} + +.repository-router-links a:hover img, +.repository-router-links a:focus-visible img { + transform: translateX(4px); +} + .selector { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); @@ -1251,11 +1301,13 @@ td a { } .responsibility-grid, - .ecosystem-repositories { + .ecosystem-repositories, + .repository-router-links { gap: 24px; } - .ecosystem-repositories { + .ecosystem-repositories, + .repository-router-links { grid-template-columns: repeat(2, minmax(0, 1fr)); } @@ -1458,6 +1510,7 @@ td a { .responsibility-grid, .ecosystem-repositories, + .repository-router-links, .deploy-grid { grid-template-columns: 1fr; } diff --git a/web-pages/product-site/templates/home.html b/web-pages/product-site/templates/home.html index a092406ee..c42f189bb 100644 --- a/web-pages/product-site/templates/home.html +++ b/web-pages/product-site/templates/home.html @@ -27,6 +27,31 @@ +
+
+

{{ '生态路由' if language == 'zh' else 'Ecosystem routing' }}

+

{{ '按工作流进入专用仓库' if language == 'zh' else 'Choose the focused repository' }}

+

{{ '部署路径适用于 FunASR 运行时;当需求由模型能力或视频工作流定义时,直接进入对应仓库。' if language == 'zh' else 'Deployment paths serve the FunASR runtime. When the requirement is defined by model capability or a video workflow, start in the focused repository.' }}

+
+ +
+

{{ '部署选择器' if language == 'zh' else 'Deployment selector' }}

diff --git a/web-pages/product-site/tests/test_output.py b/web-pages/product-site/tests/test_output.py index dafac67b4..3722d0e96 100644 --- a/web-pages/product-site/tests/test_output.py +++ b/web-pages/product-site/tests/test_output.py @@ -69,6 +69,35 @@ def test_homepage_routes_each_project_by_workload(built_site, relative, markers) assert marker in text +@pytest.mark.parametrize( + ('relative', 'heading', 'routes'), + ( + ( + 'index.html', + '按工作流进入专用仓库', + ('/go/fun-asr', '/go/sensevoice', '/go/funclip'), + ), + ( + 'en/index.html', + 'Choose the focused repository', + ('/go/fun-asr', '/go/sensevoice', '/go/funclip'), + ), + ), +) +def test_homepage_surfaces_focused_repository_router_before_deployment_choice( + built_site, relative, heading, routes +): + soup = read_soup(built_site / relative) + router = soup.select_one('[data-section="repository-router"]') + selector = soup.select_one('[data-section="deployment-selector"]') + + assert router + assert selector + assert router.get_text(' ', strip=True).find(heading) >= 0 + assert list(soup.select('section')).index(router) < list(soup.select('section')).index(selector) + assert tuple(link['href'] for link in router.select('a[href]')) == routes + + def test_every_deployment_page_has_operational_contract(built_site): registry = load_registry(SITE_ROOT / 'data' / 'deployments.json')