How the app consumes the inline assets. Everything rendered on this page goes through the tag it documents.
The inline cuts (kosmos-k-mark.svg,
kosmos-wordmark-inline.svg) are plain SVG files
with fill="currentColor" and 1em sizing. That's
the same mechanism Lucide uses — its CDN script just
swaps <i data-lucide> tags for inline
<svg> elements at runtime. Here the
injection happens server-side in the template,
so the icon arrives in the first byte of HTML, already
themed, with no JavaScript and no flash of missing icon.
currentColor only cascades to SVG that is inline
in the DOM. Through <img> the file is an
isolated document and renders black — that's the one
rule to remember.
Lives at app/templatetags/brand.py in this
workshop — copy the file into the app and adjust the
path to wherever the kit's svg/ directory
lands. It reads each file once (per process; every request
in DEBUG) and marks it safe.
# app/templatetags/brand.py
import os
import re
from django import template
from django.conf import settings
from django.utils.safestring import mark_safe
register = template.Library()
_cache = {}
_SAFE = re.compile(r"^[a-z0-9-]+$")
@register.simple_tag
def brand_svg(name):
if not _SAFE.match(name):
raise template.TemplateSyntaxError(f"bad brand_svg name: {name!r}")
if settings.DEBUG or name not in _cache:
path = os.path.join(settings.BASE_DIR, "static", "images",
"logo-variants", f"{name}.svg")
with open(path) as f:
_cache[name] = mark_safe(f.read().strip())
return _cache[name]
Wrap the tag in an element that sets color and
font-size — the SVG inherits both, like
text.
{% load brand %}
<a href="/" class="nav-brand" style="font-size: 1.4rem">
{% brand_svg "kosmos-k-mark" %}
</a>
<footer style="color: var(--ink-soft); font-size: 1.1rem">
{% brand_svg "kosmos-wordmark-inline" %}
</footer>
Which renders (live, via the tag):
The gradient twins (kosmos-k-mark-gradient.svg,
kosmos-wordmark-gradient.svg and its
-small cut) go through the same tag and keep
the 1em sizing. Instead of color they read two
tokens, --brand-grad-from and
--brand-grad-to: set them per theme, or set
both to one colour for a flat brand. Without them the cut
shows its built-in Nord pair by colour scheme.
Each file carries its own gradients, so
every inlined copy repeats their ids, and a reference
resolves to the first copy in the
document. That is harmless while the copies are visible
and share one set of tokens. If the first copy can be
display: none (a collapsed sidebar's
wordmark), or two copies need different colours, lift the
<defs> into one zero-size SVG included
once per page and leave only the paths in each cut
— what the app does.
{% include %}
— identical result if you copy the SVGs into the
templates directory; the tag just keeps them in
static/ with the rest of the kit.<use> —
one file of symbols referenced by id. The right tool at
forty icons; ceremony at two.<img> / CSS background
— fine where theming doesn't matter (a fixed night
badge); never where the mark must follow the theme.