{#
Shared template macros.
Import at the top of any template that needs them:
{% from "_macros.html" import icon, brandlink, mark, scene %}
#}
{# An icon from the inlined sprite. `name` omits the "i-" prefix. #}
{% macro icon(name, cls="") -%}
{%- endmacro %}
{% import "_art.html" as art %}
{#
The mark: the pixel mallorn leaf of the built-in themes, drawn by
`_art.html`, which scripts/build_artwork.py generates from scripts/pixel_art.py.
Every cell is classed by role and coloured from the theme's `--art-*` tokens,
so the mark follows the theme and no hex lives in a template any more -- the
vector mark it replaces carried eleven.
#}
{#
An uploaded logo replaces it, the same way `model_avatar` branches. The branch
is inside the macro rather than at each of the six call sites, so a logo
reaches the sidebar, the sign-in page, the offline page and every empty state
at once -- and so the one place that has to know the fallback exists is here.
`uid` is no longer needed (the pixel mark has no gradient ids to clash) and is
kept so the call sites stay as they are.
#}
{% macro mark(cls="brand-mark", uid="a") -%}
{% if brand.logo_url %}
{%- else %}{{ art.leaf(cls, brand.name) }}{% endif %}
{%- endmacro %}
{#
The scene on a new chat: the Doors of Durin on Moria, the round door on the
Shire. Both are drawn and the theme's base decides which shows (app.css), so
switching theme in the browser needs no reload. An uploaded logo wins here
too: an instance that has its own identity shows that, not Middle-earth.
#}
{% macro scene(cls="empty__mark") -%}
{{ art.durin("art-scene art-scene--moria") }}{{ art.smial("art-scene art-scene--shire") }}
{%- endmacro %}
{#
The wordmark as live text rather than the outlined SVG: it stays selectable,
searchable and readable to a screen reader, and scales with the user's font
size.
The accent on the capitals spelling LLM is only meaningful for the shipped
name, so it is applied only when the name *is* the shipped one. Guessing which
letters of somebody else's name to highlight would produce "InTernal AI" —
worse than plain text, and worse in a way nobody would think to look for.
#}
{% macro wordmark() -%}
{% if brand.name == "LLeMbas" %}
LLeMbas
{%- else -%}
{{ brand.name }}
{%- endif %}
{%- endmacro %}
{#
A model's avatar: the uploaded image, or a generated initial.
The fallback colour is derived from the model id, so every model gets a
stable, distinct-looking badge without an administrator having to upload
anything. Hue only -- saturation and lightness are fixed so the result always
sits legibly against both themes.
#}
{% macro model_avatar(model, cls="model-avatar") -%}
{% if model.image_path %}
{% else %}
{{ model.initial }}
{% endif %}
{%- endmacro %}
{#
The brand link in a sidebar. Named `brandlink` and not `brand`, because
`brand` is the Jinja global holding this instance's identity -- and a macro
imported under that name shadows it for the whole template, which took out
every page that imports this one at once.
#}
{% macro brandlink(href="/", uid="a") -%}
{{ mark(uid=uid) }}
{{ wordmark() }}
{%- endmacro %}
{#
A sidebar section's heading as the one control that folds it:
`[ NAME ] ⌄`, the name and the chevron inside the same