Instructions

How the app consumes the inline assets. Everything rendered on this page goes through the tag it documents.

How it works

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.

The template tag

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]

Using it

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):

When you'd reach for something else

  • {% 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.
  • Sprite + <use> — one file of symbols referenced by id. The right tool at forty icons; ceremony at two.
  • Bundler imports / components — in a React or Vue front end, import the SVG as a component; same inline destination, build-time road.
  • <img> / CSS background — fine where theming doesn't matter (a fixed night badge); never where the mark must follow the theme.