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

The gradient cuts

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.

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.