{# Finite State — Console Chrome Macros Jinja macros for the stable chrome elements of the console-style report layout. Templates import this file once and call the macros below to render the topbar, status bar, brand mark, panel headers, and KPI cells without duplicating markup. CSS for these classes is defined in _console_shell.html. Usage (import WITH CONTEXT — topbar() reads the render var `logo_path`): {% import "_console_macros.html" as fs with context %} {{ fs.topbar( crumbs=['acme', single_project_name or 'portfolio', 'triage'], meta=[{'label': 'generated', 'value': generated_at}], controls=[{'label': 'Export', 'href': '#'}] ) }} The topbar() macro renders the theme-toggle button automatically — no need to include _theme_toggle.html separately. Macros intentionally do NOT cover content-specific composition (KPI bar contents, sidebar entries, chart panel bodies) — those vary per recipe and stay inline in each template using the CSS classes from _console_shell.html. #} {# ------------------------------------------------------------------ default_logo_data_uri() The bundled Finite State wordmark as a webp data-URI — the single canonical bundled brand asset shared by every fallback path (E1). _default_logo.html and Customer Brief's PDF cover both pull from here so a brand refresh is a one-line change. Returns a full ``data:image/webp;base64,...`` string usable directly in src="". ------------------------------------------------------------------ #} {% macro default_logo_data_uri() -%}data:image/webp;base64,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{%- endmacro %} {# ------------------------------------------------------------------ brand_mark() The Finite State orange hex icon (extracted from fs-logo-light.svg). Just the icon, no wordmark — the "Finite State" text is rendered as sibling text in topbar() using the page font. Color is hardcoded to FS brand orange so the icon stays consistent in both light and dark themes (no background color worries). ------------------------------------------------------------------ #} {% macro brand_mark() -%} {%- endmacro %} {# ------------------------------------------------------------------ topbar(crumbs, meta, controls) Args: crumbs : list of strings — breadcrumbs from left to right; the LAST one renders with the .active class. Empty/None entries are skipped so callers can safely pass optional values. meta : list of {'label': str, 'value': str} — right-aligned meta items (env, scan id, generated_at, …). Rendered as "label: value". controls : list of {'label': str, 'href': str} — pill buttons. Theme toggle is appended automatically and does not need to be in this list. pill : optional string rendered as a small monospace pill after the breadcrumbs (e.g. version number). print_brand : when true (default), ALSO emit a print-only ``.print-brand`` block as a sibling of the topbar — the topbar is ``display:none`` in print, so this carries the brand (configured logo or SVG mark) onto the PDF. Callers with their own PDF cover/header (e.g. Customer Brief) pass ``print_brand=false`` to avoid a duplicate. E1: the user-configured logo (``config.logo``) is resolved centrally to a ``data:…;base64,…`` data-URI and hoisted to the top-level ``logo_path`` context var for EVERY report. When set, the brand renders it as an ```` instead of the bundled SVG hex mark. The read uses the ``is defined`` context-var pattern (macros are scope-isolated, so a DEFAULT param can't see render vars) — same as ``effective_scope`` below; this works because every console template imports these macros ``with context``. ------------------------------------------------------------------ #} {% macro topbar(crumbs=[], meta=[], controls=[], pill=None, scope=None, print_brand=True) -%} {% set _logo = logo_path if logo_path is defined else none %}
{% if _logo %}{% else %}Finite{{ brand_mark() }}State{% endif %}
{% for crumb in crumbs if crumb %} {{ crumb }} {% endfor %} {% if pill %}{{ pill }}{% endif %}
{% for m in meta %} {{ m.label }}: {{ m.value }} {% endfor %} {# B1 #15: effective-scope meta + active-filter chips. ``scope`` may be passed explicitly OR (preferred) read from the ``effective_scope`` render- context variable when the report imports these macros ``with context``. Jinja macros are scope-isolated, so a macro DEFAULT param can't read a render var — hence the body-level fallback guarded by ``is defined``. #} {% set _scope = scope if scope is not none else (effective_scope if effective_scope is defined else none) %} {% if _scope %} Scope: {{ _scope.label }}{% if _scope.version %} @ {{ _scope.version }}{% endif %} {% for chip in _scope.active_filters %} {{ chip.label }}: {{ chip.value }} {% endfor %} {% endif %} {# Connection badge injected by _action_buttons.html JS when served via fs-report serve. Inline here so the serve app's fixed-position overlay doesn't sit on top of the theme toggle. #} {% include "_theme_toggle.html" %} {% for c in controls %} {{ c.label }} {% endfor %}
{# E1: print-only brand block. The topbar is ``display:none`` in print (_console_shell.html @media print), so without this the PDF loses all branding. Sibling of the topbar; ``display:none`` on screen, shown in print (CSS in _console_shell.html). Honors the configured logo with the SVG mark as fallback — same precedence as the topbar above. Suppressed (``print_brand=false``) by reports with their own PDF cover/header so the brand isn't duplicated. #} {% if print_brand %} {% endif %} {%- endmacro %} {# ------------------------------------------------------------------ status_bar(items, version) Args: items : list of strings — left-aligned status items (record count, filter description, etc.). Plain text; styled monospace. version : optional string — right-aligned version label (e.g. "v1.9.9"). Rendered muted. Renders a sticky bottom bar that hides in print. ------------------------------------------------------------------ #} {% macro status_bar(items=[], version=None) -%}
{% for item in items %}
{{ item }}
{% endfor %}
{% if version %}
{{ version }}
{% endif %}
{%- endmacro %} {# ------------------------------------------------------------------ panel_head(title, meta) Args: title : string — h2 inside the panel. Renders with the accent ::before bar handled by .panel h2 CSS. meta : optional string — small monospace meta text on the right (e.g. counts, sort order). Use inside
. Body content is written inline by the caller. ------------------------------------------------------------------ #} {% macro panel_head(title, meta=None) -%}

{{ title }}

{% if meta %}
{{ meta }}
{% endif %}
{%- endmacro %} {# ------------------------------------------------------------------ kpi_cell(label, value, delta, dot) Args: label : uppercase short label (e.g. "Critical", "KEV / Exploit") value : the big tabular number/text (any type — rendered as string) delta : optional string — small line under the value (e.g. "+1 vs last scan", "58% coverage", "±0"). When the text starts with "+" or "−" or contains the word "vs", consider passing delta_class="up"|"down" for color coding. delta_class : optional string — "up" (green) or "down" (red) dot : optional severity dot color — pass "critical"|"high"| "medium"|"low"|"info"|"total" to render a colored dot next to the label. Omit for no dot. ------------------------------------------------------------------ #} {% macro kpi_cell(label, value, delta=None, delta_class=None, dot=None) -%}
{% if dot %}{% endif %}{{ label }}
{{ value }}
{% if delta %}
{{ delta }}
{% endif %}
{%- endmacro %}