{% extends "brickwork/shell/base.html" %} {% load i18n %} {% comment %} Marketing shell (04-interfaces.md section 4d, 1.2.0, BR-BW-MKT-005): the public-site counterpart of shell/app.html. It reuses base.html's document skeleton (the {% static %} CSS link, the theme/density/dir attributes on , the skip link, the no-JS floor, the toast/modal roots) and adds only the public header/nav/footer regions the app shell does not have. A marketing page {% extends %} this shell and is itself {% extends %}d by a consuming page (BR-BW-PAGE-001 at marketing scope), never {% include %}d. Named blocks (semver-public, BR-BW-TPL-001), all empty-graceful: marketing_header default: a header row with brand_logo/brand_wordmark at the inline start and marketing_nav at the end. brand_logo wrapped in the brickwork-owned .bw-marketing-header__brand-mark element (#83, the app shell's brickwork#93 wrapper precedent): an img/svg dropped in is capped at --bw-component-logo-height (2rem) with width following the intrinsic ratio, and the wrapper stays flex: 0 0 auto so the nav/actions keep the remaining width. Override the token (or the zero-specificity rule) to resize; an unfilled block leaves an :empty wrapper that collapses to nothing. brand_wordmark wrapped in .bw-marketing-header__brand-wordmark, the same treatment as brand_logo (a text wordmark is unaffected: the height cap targets only img/svg). marketing_nav the primary public nav: a plain list of links, no active-route resolver dependency (a marketing site's nav is a small fixed set, unlike the app shell's {% bw_nav %}). marketing_actions header-end CTA cluster (e.g. "Sign in" + "Get started"); see the auth-aware pattern below (#85). content the page body; the one region a page fills. marketing_footer default: a multi-column footer with link groups and a fine-print row (footer_legal). footer_legal No-JS floor (BR-BW-HTMX-001): the shell requires no Alpine or htmx. The header nav renders as plain links; a consumer wanting a mobile nav disclosure composes the existing _disclosure.html/_account_menu.html pattern (the same way the app shell's switcher slot does), never a brickwork-shipped default here. Auth-aware actions (#85): brickwork never reads auth state itself (state is host-injected, per the ADR-025 responsibility model, exactly as the app nav's visibility mechanism receives its request). The supported pattern is the consumer branching its marketing_actions block on request.user.is_authenticated (requires django.template.context_processors.request in the consumer's TEMPLATES options; note Django's logout is POST-only, hence the form): {% block marketing_actions %} {% if request.user.is_authenticated %} Dashboard {% csrf_token %} {% bw_button "Log out" type="submit" variant="secondary" %} {% else %} Sign in {% bw_button "Get started" variant="primary" href="/signup/" %} {% endif %} {% endblock %} The worked, annotated version lives in docs/INTEGRATION.md section 8. A bare in this slot is styled by marketing.css (label voice, muted ink, never UA default blue, BR-BW-MKT-002); {% bw_button %} carries the CTA weight. Content measure: the marketing content wrapper uses --bw-component-content-max-width-marketing (80rem), wider than the app shell's --bw-component-content-max-width (72rem) cap, since a marketing canvas wants a wider column than a console (04-interfaces.md 4d). States: none of its own; the header/nav/actions/footer regions are plain markup with no open/closed or collapsed state. A consumer's own mobile nav disclosure (composed from _disclosure.html/_account_menu.html) carries whatever states that component documents; this shell ships no default one. Accessibility: inherits the skip link and lang/dir/theme attributes from base.html. Its own contribution is as the content region, marketing_nav wrapped in , and themed colour for bare prose links in the footer and actions slots (never UA-default blue, BR-BW-MKT-002). Covered by axe.spec.mjs against landing-*.html, pricing-*.html, about-*.html and sections-*.html, and by the archetype harness against every marketing-family archetype (landing, pricing, about), both themes, the full W0.1 width matrix. Responsive: no breakpoint switch. The header's brand/nav/actions row is display: flex; flex-wrap: wrap at every width (fixed after icvoss/django-brickwork#125, which found the unwrapped row overflowing the viewport at 320px): narrow viewports wrap the row onto further lines rather than switching layout at a named breakpoint. The content column and footer are both capped at --bw-component-content-max-width-marketing and centred, fluid below that width. {% endcomment %} {% block shell_variant %}marketing{% endblock %} {% block shell %} {% block marketing_header %} {% block brand_logo %}{% endblock %} {% block brand_wordmark %}{% endblock %} {% block marketing_nav %}{% endblock %} {% block marketing_actions %}{% endblock %} {% endblock %} {% block content %}{% endblock %} {% endblock %}