Skip to main content

max / makenotwork

4.3 KB · 78 lines History Blame Raw
1 {# Everything from <!doctype> down to the last script in the head is quasi's,
2 emitted by the same shell a described screen renders through. See
3 crate::shell: the site is being converted a screen at a time, and two heads
4 written by two hands drift in ways nothing catches. What is left here is
5 what a template has to own, because Askama renders these blocks in place and
6 no caller ever holds them as a string. #}
7 {{ crate::shell::head()|safe }}
8 {% if let Some(token) = csrf_token %}<meta name="csrf-token" content="{{ token }}">{% endif %}
9 <title>{% block title %}Makenotwork{% endblock %}</title>
10 <meta name="description" content="{% block meta_description %}Sell your work directly. 0% platform fee, only Stripe's ~3% processing. Music, software, writing, and more.{% endblock %}">
11
12 {# Global OG / Twitter card metadata. Per-page templates emit their own
13 og:title / og:description / og:url / og:image / twitter:* tags from
14 within {% block head %}; only the page-invariant tags live here.
15 Pages without overrides (cart, library, policy) get a generic but
16 valid card from site_name + type + card.
17
18 og:type and twitter:card are blocks rather than plain tags because a
19 page needs to CONTRADICT them, not add to them: an item is a product,
20 a post is an article, a page with no image wants a summary card. Emitted
21 unconditionally they shipped twice on every page that had its own, and
22 a consumer that takes the first occurrence read this generic value and
23 never the page's. Override the block; do not emit the tag again inside
24 {% block head %}. #}
25 <meta property="og:site_name" content="Makenotwork">
26 {% block og_type %}<meta property="og:type" content="website">{% endblock %}
27 {% block social_card %}<meta name="twitter:card" content="summary_large_image">{% endblock %}
28
29 {% block head %}{% endblock %}
30 </head>
31 <body{{ crate::shell::body_attrs()|safe }}{% block body_attrs %}{% endblock %}>
32 <a href="#main-content" class="skip-to-main">Skip to main content</a>
33 <main id="main-content">
34 {% block content %}{% endblock %}
35 </main>
36
37 <footer class="site-footer">
38 <div class="site-footer-links">
39 <a href="/pricing">Pricing</a>
40 <a href="/creators">Creators</a>
41 <a href="/docs">Docs</a>
42 <a href="/policy">Legal</a>
43 <a href="/docs/credits">Credits</a>
44 {# Linked only while a published changelog project exists; the route
45 404s otherwise. See crate::changelog. #}
46 {% if crate::changelog::is_published() %}<a href="/changelog">Changelog</a>{% endif %}
47 <a href="mailto:info@makenot.work">Contact</a>
48 <a href="/health" title="Service status and uptime">Status</a>
49 <a href="#" data-prevent data-action="showWhatsNewModal">What's new</a>
50 <a href="#" data-prevent data-action="toggleShortcutsHelp" title="Keyboard shortcuts (?)">Shortcuts</a>
51 </div>
52 <p>&copy; 2026 Make Creative, LLC</p>
53 </footer>
54
55 <!-- Toast notification container -->
56 <div id="notifications" class="toast-container" role="alert" aria-live="polite"></div>
57
58 <!-- Delegated on* handlers, extracted from inline attributes so the CSP can
59 drop script-src 'unsafe-inline'. The data-action dispatcher + core
60 primitives now live in the typed core module (frontend/src/core),
61 loaded as an ES module in <head> via crate::shell; these classic
62 shims resolve through its registry / window bridge. -->
63 <script src="/static/actions-pages.js?v=0701"></script>
64 <script src="/static/actions-partials.js?v=0701"></script>
65 <script src="/static/actions-tabs.js?v=0701"></script>
66 <script src="/static/actions-dashboards.js?v=0701"></script>
67 <script src="/static/synckit-billing.js?v=0620"></script>
68 <script src="/static/synckit-tabs.js?v=0623"></script>
69 <script src="/static/whats_new.js?v=0522"></script>
70 {# Binds the described markdown field's Write/Preview chrome wherever one
71 appears. Loaded here rather than beside each of the four surfaces because
72 three of them arrive inside HTMX-swapped partials, and the binder rescans
73 on settle. #}
74 <script src="/static/markdown-editor.js?v=0820"></script>
75 {% block scripts %}{% endblock %}
76 </body>
77 </html>
78