1dd510285a
- .sf-tp-icon CSS width/height (Safari doesn't support var() in SVG presentation attributes); --sm variant class replaces size= call sites - search icon centered via translateY, decoupled from input height - bare-arrow test: full charset (→←↗↘⌕▾) + line-level › whitelist - new test: site.html tp_arrow must stay in sync with macro library path Co-Authored-By: Claude Code <noreply@anthropic.com>
44 lines
5.1 KiB
HTML
44 lines
5.1 KiB
HTML
{# trade-pro macro library: passthrough copy of the shared
|
||
themes/_professional_components.html with English strings, plus the
|
||
trade-pro inline SVG icon set (Task 9). Icons are decorative
|
||
server-side inlines: no JS dependency, currentColor strokes. #}
|
||
{# ── SVG icon set (Task 9) ──────────────────────────────────────────────
|
||
Style contract: 24×24 viewBox, stroke=currentColor, stroke-width 1.5,
|
||
fill none, round caps/joins — the same modern line language as the
|
||
ported cms design. Every glyph is ONE <path> (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'] -%}
|
||
<svg class="sf-tp-icon{% if cls %} {{ cls }}{% endif %}" width="{{ size if size else 'var(--sf-tp-icon-size-md, 20px)' }}" height="{{ size if size else 'var(--sf-tp-icon-size-md, 20px)' }}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="{{ _d }}"/></svg>
|
||
{%- endmacro %}
|
||
{% macro cover(item, kind='product') %}
|
||
{% if item.cover %}<img class="pro-photo" src="{{ safe_image(item.cover) }}" alt="{{ item.title }}" loading="lazy">
|
||
{% else %}<div class="pro-art pro-art-{{ kind }}"><span class="pro-art-ring"></span><span class="pro-art-center">{{ (item.title or 'SF')[:2] }}</span><span class="pro-art-label">{{ kind|upper }}</span></div>{% endif %}
|
||
{% endmacro %}
|
||
{% macro card(item, kind='product', position=0) %}
|
||
<a class="pro-card pro-card-{{ kind }}" href="{{ safe_href(item.route) }}" data-category="{{ fields_of(item).get('category','') }}" data-brand="{{ fields_of(item).get('brand','') }}">
|
||
<div class="pro-card-cover">{{ cover(item,kind) }}</div>
|
||
<div class="pro-card-body"><div class="pro-card-meta"><span>{{ 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') }}</span><span>{{ '%02d'|format(position+1) }}</span></div>
|
||
<h3>{{ item.title }}</h3><p>{{ (item.summary or '')[:128] }}</p><span class="pro-card-link">View details {{ icon('arrow-right') }}</span></div>
|
||
</a>
|
||
{% endmacro %}
|
||
{% macro grid(items,kind='product') %}<div class="pro-grid pro-grid-{{ kind }}">{% for item in items %}{{ card(item,kind,loop.index0) }}{% else %}<div class="pro-empty">No published content in this section yet.</div>{% endfor %}</div>{% endmacro %}
|
||
{% macro section_title(eyebrow,heading,href='') %}<div class="pro-section-head"><div><span class="pro-eyebrow">{{ eyebrow }}</span><h2>{{ heading }}</h2></div>{% if href %}<a class="pro-text-link" href="{{ href }}">Browse all {{ icon('arrow-right') }}</a>{% endif %}</div>{% endmacro %}
|
||
{% macro filters() %}<div class="pro-filter-panel"><label><span>Search</span><span class="pro-filter-search-box">{{ icon('search') }}<input type="search" data-pro-filter-search placeholder="Filter by name or content"></span></label><label><span>Brand</span><select data-pro-filter-brand><option value="">All brands</option></select></label><label><span>Category</span><select data-pro-filter-category><option value="">All categories</option></select></label><span class="pro-filter-count" data-pro-filter-count role="status"></span></div>{% endmacro %}
|
||
{% macro footer_links(nav) %}<ul>{% for item in nav[:7] %}<li><a href="{{item.route}}">{{item.title}} {{ icon('arrow-right', cls='sf-tp-icon--sm') }}</a></li>{% endfor %}</ul>{% endmacro %}
|
||
{% macro body_copy(content,page) %}{% if content %}<div class="pro-rich">{{ content }}</div>{% elif page.summary %}<p class="pro-lead">{{ page.summary }}</p>{% else %}<p class="pro-muted">Complete this page's content in the admin console.</p>{% endif %}{% endmacro %}
|