Marketing and public web
Landing
A finished page under Kiln. Copy it and it is yours outright: unlike a brickwork component or shell, it never upgrades under semver.
Static reference: This preview uses fictional logos and sample metrics. Navigation and action links use the source example’s sample destinations; they do not form a connected demo.
Invoicing
Invoicing that chases itself
Northwind raises your invoices, sends the reminders, and tells you who is about to pay late. You do the work. It does the asking.
Trusted by finance teams at
Everything the chasing needs
The parts of getting paid that nobody wants to do by hand.
Automatic reminders
Send a clear follow-up before an invoice becomes awkward.
Due-date planning
See which invoices need attention before the week closes.
Payment matching
Keep paid invoices visible beside the work that remains.
Built for the boring half of getting paid
See what changes in the first quarter
Most teams cut days-to-pay without hiring anyone. Start free, import when you are ready.
What changes in the first quarter
What finance teams say after a quarter
We cut our average days-to-pay from 38 to 21 without hiring anyone. The reminders just go out.
I imported two years of invoices on a Tuesday afternoon and the first reminders went out that evening. There was no implementation project.
The thing I was worried about was sounding aggressive to customers I like. It stops the moment they pay, so nobody has been chased for an invoice they already settled.
Stop writing chase emails
Free for 30 days. No card, no setup call, no data import to sit through.
Scroll inside the frame to inspect the full page.
{% extends "brickwork_marketing/shell/marketing.html" %}
{% comment %}
A product landing page.
COPY THIS FILE into your project and edit it. It is not on the template loader
path, so you cannot extend it (ADR-056).
THIS IS THE PAGE THAT MOTIVATED ADR-056. Before 2.0.0 brickwork shipped a
landing page you extended and fed a flat context bag: heading, lede,
cta_heading, logo_cloud_heading, features_heading, and so on. That inverted
ownership of your own landing page (a pin bump could reorder your sections) and
forced prefix soup, because one page cannot use "heading" for six sections.
Here instead every section carries its own content, scoped to its own include.
There is no page-level bag, no prefix soup, and reordering, dropping, or
duplicating a section is editing this file, which is yours.
What your view must supply: nothing at all for the copy. List-shaped sections
cannot be built inline, so they come from context:
features [{icon, heading, body, url?}]
logos the logo cloud's items
feature_rows [{heading, body, media?}] for the alternating depth band
footer_groups [{heading, links:[{label, href}]}] for the footer include
Optional for a media-led hero (scorecard S5):
hero_media pre-rendered safe HTML for media_placement="beside"
(prefer a .bw-product-chrome / .bw-product-chrome-stack frame
with an illustrative SVG stage, not a flat placeholder panel)
Everything else below is typed straight into the template.
States: the auth-aware header actions branch on request.user.is_authenticated
(a signed-in vs signed-out header state); every composed component's own
states (hero, logo cloud, feature grid, feature rows, cta split, stat band,
testimonial, cta bleed) are unchanged, see each component's own header.
Accessibility: inherits shell/marketing.html's skip link and header/footer
landmarks; the composed hero renders the page's own <h1>. Covered by the
archetype harness's full gate sweep (render, axe WCAG 2.2 AA, no
horizontal overflow, light/dark distinctness, skip-link first-tab-stop
with JS disabled) at every W0.1 breakpoint, both themes, and directly by
axe.spec.mjs against landing-*.html, this page's own hand-maintained
fixture (also the fixture hero-placement-*.html and cta-width-*.html
compose their OWN standalone _hero.html/_cta.html renders against, not
this page, for the media_placement and width axes this page's own hero
and CTA do not exercise).
Responsive: no breakpoint switch of its own; inherits shell/marketing.html's
fluid header wrap and content-column cap. Each composed section carries
whatever responsive behaviour its own header documents (feature grid: 1/2/3
columns at sm/lg; feature rows and cta split: stack then two columns from
md; footer groups: 1 then 2 columns via .bw-marketing-footer__groups; the
testimonial grid: auto-fit columns; the rest: fluid, no named breakpoint).
{% endcomment %}
{% load brickwork_components %}
{% block page_title %}Northwind - invoicing that chases itself{% endblock %}
{% block brand_wordmark %}Northwind{% endblock %}
{% comment %}
Package-owned mobile disclosure (icvoss/django-brickwork#263 / #509): include
the toggle as a sibling of the nav via marketing_nav_region. Do not fill the
outer marketing_header and reproduce brand/nav/actions verbatim.
{% endcomment %}
{% block marketing_nav_region %}
{% include "brickwork_marketing/components/_mobile_nav_toggle.html" %}
<nav class="bw-site-header__nav" aria-label="Primary">
{% block marketing_nav %}
<a href="/features/">Features</a>
<a href="/pricing/">Pricing</a>
<a href="/customers/">Customers</a>
<a href="/docs/">Docs</a>
{% endblock %}
</nav>
{% endblock %}
{% comment %}
Auth-aware header actions. brickwork never reads auth state itself, so this is
your branch, not a package feature. Note Django's logout is POST-only.
{% endcomment %}
{% block marketing_actions %}
{% if request.user.is_authenticated %}
<a href="/app/">Go to app</a>
{% else %}
<a href="/accounts/login/">Sign in</a>
{% bw_button "Start free trial" variant="primary" href="/accounts/signup/" %}
{% endif %}
{% endblock %}
{% block content %}
{% comment %}
The hero. CTAs take flat label/url pairs, so a plain template can drive them
with no view involvement. (They also accept {label, url} dicts if the data
already exists in your context; the dict wins when both are given.)
hero_media is optional pre-rendered safe HTML for the media column;
media_placement="beside" is the screenshot/diagram shape. Prefer product
chrome (see fixture) over a flat coloured rectangle.
{% endcomment %}
{% include "brickwork_marketing/components/_hero.html" with eyebrow="Invoicing" heading="Invoicing that chases itself" lede="Northwind raises your invoices, sends the reminders, and tells you who is about to pay late. You do the work. It does the asking." primary_cta_label="Start free trial" primary_cta_href="/accounts/signup/" secondary_cta_label="Book a demo" secondary_cta_href="/demo/" media=hero_media media_placement="beside" %}
{% comment %}
Logo cloud. List-shaped, so logos comes from context.
{% endcomment %}
{% include "brickwork_marketing/components/_logo_cloud.html" with heading="Trusted by finance teams at" logos=logos greyscale=True %}
{% comment %}
Feature grid. Also list-shaped: build features in your view as
[{icon, heading, body, url}]. Give an item a url and the whole card becomes
a link; leave it off and the card stays a plain non-interactive block, never
a clickable-looking card with nowhere to go.
{% endcomment %}
{% include "brickwork_marketing/components/_feature_grid.html" with heading="Everything the chasing needs" lede="The parts of getting paid that nobody wants to do by hand." items=features columns=3 %}
{% comment %}
Alternating feature rows: the two or three capabilities that sell the
product, each with its own media. List-shaped media HTML comes from context
(same product-chrome idea as the hero).
{% endcomment %}
{% include "brickwork_marketing/components/_feature_rows.html" with heading="Built for the boring half of getting paid" items=feature_rows %}
{% comment %}
Mid-page CTA split: a nudge, not the page ending. Sibling of the closing
bleed below.
{% endcomment %}
{% include "brickwork_marketing/components/_cta_split.html" with heading="See what changes in the first quarter" body="Most teams cut days-to-pay without hiring anyone. Start free, import when you are ready." primary_cta_label="Start free trial" primary_cta_href="/accounts/signup/" secondary_cta_label="Talk to us" secondary_cta_href="/contact/" %}
{% comment %}
Stats. The band takes a list too, but a three-number band is often clearer
written straight into your view as [{value, label}].
{% endcomment %}
{% include "brickwork_marketing/components/_stat_band.html" with heading="What changes in the first quarter" stats=stats %}
{% comment %}
Quote grid: three testimonials that answer different doubts. Markup for the
grid wrapper lives here (nothing in the kit arranges several quotes); each
card is still the shipped _testimonial.html include.
{% endcomment %}
<section class="bw-testimonial-grid-section">
<h2 class="bw-testimonial-grid-section__heading">What finance teams say after a quarter</h2>
<div class="bw-testimonial-grid">
{% include "brickwork_marketing/components/_testimonial.html" with quote="We cut our average days-to-pay from 38 to 21 without hiring anyone. The reminders just go out." author="Priya Raman" role="Finance Director, Halden Group" %}
{% include "brickwork_marketing/components/_testimonial.html" with quote="I imported two years of invoices on a Tuesday afternoon and the first reminders went out that evening. There was no implementation project." author="Daniel Okoro" role="Head of Operations, Cransley Freight" %}
{% include "brickwork_marketing/components/_testimonial.html" with quote="The thing I was worried about was sounding aggressive to customers I like. It stops the moment they pay, so nobody has been chased for an invoice they already settled." author="Marta Lindqvist" role="Owner, Lindqvist Joinery" %}
</div>
</section>
{% comment %}
Closing CTA as inverse full-bleed: once per page, at the end.
{% endcomment %}
{% include "brickwork_marketing/components/_cta_bleed.html" with heading="Stop writing chase emails" body="Free for 30 days. No card, no setup call, no data import to sit through." primary_cta_label="Start free trial" primary_cta_href="/accounts/signup/" secondary_cta_label="Book a demo" secondary_cta_href="/demo/" %}
{% endblock %}
{% block marketing_footer %}
{% comment %}
Footer link groups via the package include. Pass footer_groups from the
view as [{heading, links:[{label, href}]}]; the include emits the shared
.bw-marketing-footer__groups vocabulary (#500 / #542).
{% endcomment %}
{% include "brickwork_marketing/components/_marketing_footer_groups.html" with groups=footer_groups %}
{% endblock %}
{% block footer_legal %}
<p>Copyright 2026 Northwind Software Ltd. <a href="/privacy/">Privacy</a> <a href="/terms/">Terms</a></p>
{% endblock %}
Details
| Kind | Page example |
|---|---|
| Used in | Marketing and public web |
Composed from
| Template | Description |
|---|---|
brickwork/components/_button.html |
A button or link styled as a button, in several variants. |
brickwork_marketing/components/_cta_bleed.html |
A full-bleed call-to-action band that runs edge to edge. |
brickwork_marketing/components/_cta_split.html |
A split call-to-action: copy on one side, actions on the other. |
brickwork_marketing/components/_feature_grid.html |
A grid of features, each with an icon, heading, and body. |
brickwork_marketing/components/_feature_rows.html |
Alternating feature rows with media and copy. |
brickwork_marketing/components/_hero.html |
A page-opening band with a heading, lede, and call to action. |
brickwork_marketing/components/_logo_cloud.html |
A row of partner or customer logos. |
brickwork_marketing/components/_marketing_footer_groups.html |
Named columns of footer links for the marketing shell footer region. |
brickwork_marketing/components/_mobile_nav_toggle.html |
A package-owned disclosure that collapses marketing nav and actions below the large breakpoint. |
brickwork_marketing/components/_stat_band.html |
A row of key figures, styled for a marketing page. |
brickwork_marketing/components/_testimonial.html |
A quote with attribution and an optional logo. |
brickwork_marketing/shell/marketing.html |
The public marketing shell: header, nav, content, and footer. |