{% comment %} Testimonial (04-interfaces.md section 4d): a quote card, the social-proof block. Structural, consumed via {% include %} (BR-BW-MKT ยง4d structural- include doctrine). Required context: quote. Optional context: author (str): the attribution name. role (str): the attribution line (e.g. "CTO, Acme Ltd"). avatar (str, an image URL): rendered with alt implied from author (never an unlabelled image, per the standing a11y non-goal). Omitted renders a text-only quote card, never a broken image. logo (safe string): a company logo, pre-rendered safe HTML. The caller owns escaping, matching _stat.html's sparkline convention. Layout note (#86): the root carries no block margins of its own (the UA
margins are neutralised at zero specificity in the CSS), so the marketing shell's section rhythm (.bw-marketing__content > * + *) owns the gap above a composed testimonial. avatar is already a flat string (#98): fully template-authorable via {% include ... with %} as-is, nothing dict-shaped or list-shaped. logo is the one exception (pre-rendered safe HTML a plain template cannot build), so it also ships as the named block below. Named blocks (semver-public, BR-BW-TPL-001): logo, empty by default, wrapping the existing {% if logo %} rendering. A call site supplying only the logo context variable (the pre-existing path) renders byte-identical output to before this block existed. A caller who wants to author the mark inline (examples/sections/testimonial/logo-and-quote.html's blocker) extends this template and fills the block instead of supplying mark_safe(...) markup from a view. KNOWN LIMITATION, stated rather than papered over. This block sits inside the figcaption, which only renders when author, role, avatar or logo is truthy. A caller who fills the block but sets none of those four gets nothing: Django cannot test whether a block was overridden, so the gate cannot open itself on the caller's behalf. Filling the block therefore means setting one of the four, which for a mark beside an attribution is the normal case (author or role is almost always present). The workaround for a genuinely unattributed mark, passing a placeholder logo=" " purely to open the gate, is a poor contract and is NOT recommended; if that case turns out to matter, the fix is a structural one to the figcaption, not a sentinel. Tracked as icvoss/django-brickwork#171. Placing the block outside the gate was tried and rejected: it renders whenever filled, but then an override no longer REPLACES the logo context variable, so both would render at once. One region, one winner, matching the _empty_state precedent, is worth more than reaching the unattributed edge case. {% endcomment %} {% if quote %}

{{ quote }}

{% if author or role or avatar or logo %}
{% if avatar %}{{ author }}{% endif %}
{% if author %}{{ author }}{% endif %} {% if role %}{{ role }}{% endif %}
{% block logo %}{% if logo %}{% endif %}{% endblock %}
{% endif %}
{% endif %}