django-brickwork 1.0.0rc1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. django_brickwork-1.0.0rc1/LICENSE +21 -0
  2. django_brickwork-1.0.0rc1/NOTICE +62 -0
  3. django_brickwork-1.0.0rc1/PKG-INFO +193 -0
  4. django_brickwork-1.0.0rc1/README.md +157 -0
  5. django_brickwork-1.0.0rc1/pyproject.toml +128 -0
  6. django_brickwork-1.0.0rc1/setup.cfg +4 -0
  7. django_brickwork-1.0.0rc1/src/brickwork/__init__.py +20 -0
  8. django_brickwork-1.0.0rc1/src/brickwork/apps.py +25 -0
  9. django_brickwork-1.0.0rc1/src/brickwork/conf.py +65 -0
  10. django_brickwork-1.0.0rc1/src/brickwork/context_processors.py +66 -0
  11. django_brickwork-1.0.0rc1/src/brickwork/exceptions.py +15 -0
  12. django_brickwork-1.0.0rc1/src/brickwork/icons/__init__.py +52 -0
  13. django_brickwork-1.0.0rc1/src/brickwork/icons/registry.py +176 -0
  14. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/arrow-down.svg +16 -0
  15. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/arrow-up-down.svg +18 -0
  16. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/arrow-up.svg +16 -0
  17. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/bell.svg +16 -0
  18. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/calendar.svg +18 -0
  19. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/check.svg +15 -0
  20. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-down.svg +15 -0
  21. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-left.svg +15 -0
  22. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-right.svg +15 -0
  23. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-up.svg +15 -0
  24. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-alert.svg +17 -0
  25. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-check.svg +16 -0
  26. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-help.svg +17 -0
  27. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-x.svg +17 -0
  28. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/copy.svg +16 -0
  29. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/download.svg +17 -0
  30. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/ellipsis-vertical.svg +17 -0
  31. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/ellipsis.svg +17 -0
  32. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/external-link.svg +17 -0
  33. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/eye-off.svg +18 -0
  34. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/eye.svg +16 -0
  35. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/file-text.svg +19 -0
  36. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/filter.svg +15 -0
  37. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/folder.svg +15 -0
  38. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/home.svg +16 -0
  39. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/info.svg +17 -0
  40. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/loader-circle.svg +15 -0
  41. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/lock.svg +16 -0
  42. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/log-in.svg +17 -0
  43. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/log-out.svg +17 -0
  44. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/menu.svg +17 -0
  45. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/minus.svg +15 -0
  46. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/panel-left.svg +16 -0
  47. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/pencil.svg +16 -0
  48. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/plus.svg +16 -0
  49. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/save.svg +17 -0
  50. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/search.svg +16 -0
  51. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/settings.svg +16 -0
  52. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/square-pen.svg +16 -0
  53. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/trash-2.svg +19 -0
  54. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/triangle-alert.svg +17 -0
  55. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/upload.svg +17 -0
  56. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/user.svg +16 -0
  57. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/users.svg +18 -0
  58. django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/x.svg +16 -0
  59. django_brickwork-1.0.0rc1/src/brickwork/models.py +156 -0
  60. django_brickwork-1.0.0rc1/src/brickwork/py.typed +0 -0
  61. django_brickwork-1.0.0rc1/src/brickwork/services/__init__.py +6 -0
  62. django_brickwork-1.0.0rc1/src/brickwork/services/brand_css.py +195 -0
  63. django_brickwork-1.0.0rc1/src/brickwork/services/forms.py +61 -0
  64. django_brickwork-1.0.0rc1/src/brickwork/services/navigation.py +169 -0
  65. django_brickwork-1.0.0rc1/src/brickwork/services/token_manifest.py +79 -0
  66. django_brickwork-1.0.0rc1/src/brickwork/services/tokens.py +99 -0
  67. django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/brickwork.css +1 -0
  68. django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/brickwork.js +1 -0
  69. django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/tailwind-theme.css +95 -0
  70. django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/token-manifest.json +301 -0
  71. django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/tokens.css +507 -0
  72. django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/tokens.js +304 -0
  73. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_account_menu.html +44 -0
  74. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_alert.html +34 -0
  75. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_badge.html +26 -0
  76. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_breadcrumbs.html +30 -0
  77. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_bulk_actions_bar.html +71 -0
  78. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_button.html +25 -0
  79. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_card.html +57 -0
  80. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_combobox.html +182 -0
  81. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_data_table.html +196 -0
  82. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_disclosure.html +47 -0
  83. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_dropdown.html +61 -0
  84. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_dropzone.html +53 -0
  85. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_empty_state.html +26 -0
  86. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_filter_bar.html +44 -0
  87. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_modal.html +133 -0
  88. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_page_header.html +19 -0
  89. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_pagination.html +46 -0
  90. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_progress.html +54 -0
  91. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_skeleton.html +29 -0
  92. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_slide_over.html +150 -0
  93. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_spinner.html +10 -0
  94. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_stat.html +66 -0
  95. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_stepper.html +71 -0
  96. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_tabs.html +98 -0
  97. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_tag_input.html +78 -0
  98. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_toast.html +59 -0
  99. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_toast_region.html +47 -0
  100. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_toggle.html +40 -0
  101. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_tooltip.html +62 -0
  102. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/forms/_field.html +41 -0
  103. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/forms/_form.html +71 -0
  104. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/forms/_form_errors.html +19 -0
  105. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/nav/_nav.html +54 -0
  106. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/_table_card.html +12 -0
  107. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/dashboard.html +39 -0
  108. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/detail.html +39 -0
  109. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/list.html +50 -0
  110. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/wizard.html +73 -0
  111. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/app.html +129 -0
  112. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/auth.html +23 -0
  113. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/base.html +72 -0
  114. django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/centred.html +17 -0
  115. django_brickwork-1.0.0rc1/src/brickwork/templatetags/__init__.py +1 -0
  116. django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_components.py +168 -0
  117. django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_forms.py +222 -0
  118. django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_icons.py +109 -0
  119. django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_interactions.py +487 -0
  120. django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_nav.py +138 -0
  121. django_brickwork-1.0.0rc1/src/brickwork/tokens/__init__.py +21 -0
  122. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/component.tokens.json +226 -0
  123. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/density.comfortable.tokens.json +39 -0
  124. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/density.compact.tokens.json +39 -0
  125. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/density.spacious.tokens.json +39 -0
  126. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/motion.tokens.json +39 -0
  127. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/primitive.tokens.json +120 -0
  128. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/semantic.dark.tokens.json +453 -0
  129. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/semantic.light.tokens.json +463 -0
  130. django_brickwork-1.0.0rc1/src/brickwork/tokens/source/typography.tokens.json +90 -0
  131. django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/PKG-INFO +193 -0
  132. django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/SOURCES.txt +171 -0
  133. django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/dependency_links.txt +1 -0
  134. django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/requires.txt +12 -0
  135. django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/top_level.txt +1 -0
  136. django_brickwork-1.0.0rc1/tests/test_account_menu.py +79 -0
  137. django_brickwork-1.0.0rc1/tests/test_brand_css.py +116 -0
  138. django_brickwork-1.0.0rc1/tests/test_brand_hook.py +181 -0
  139. django_brickwork-1.0.0rc1/tests/test_breadcrumbs.py +66 -0
  140. django_brickwork-1.0.0rc1/tests/test_card.py +172 -0
  141. django_brickwork-1.0.0rc1/tests/test_combobox.py +252 -0
  142. django_brickwork-1.0.0rc1/tests/test_components.py +164 -0
  143. django_brickwork-1.0.0rc1/tests/test_consumer_smoke.py +204 -0
  144. django_brickwork-1.0.0rc1/tests/test_context_processors.py +61 -0
  145. django_brickwork-1.0.0rc1/tests/test_data_table.py +203 -0
  146. django_brickwork-1.0.0rc1/tests/test_disclosure.py +104 -0
  147. django_brickwork-1.0.0rc1/tests/test_dropdown.py +181 -0
  148. django_brickwork-1.0.0rc1/tests/test_feedback.py +206 -0
  149. django_brickwork-1.0.0rc1/tests/test_filter_bar.py +76 -0
  150. django_brickwork-1.0.0rc1/tests/test_forms.py +317 -0
  151. django_brickwork-1.0.0rc1/tests/test_icons.py +173 -0
  152. django_brickwork-1.0.0rc1/tests/test_inputs.py +354 -0
  153. django_brickwork-1.0.0rc1/tests/test_integration.py +432 -0
  154. django_brickwork-1.0.0rc1/tests/test_modal.py +148 -0
  155. django_brickwork-1.0.0rc1/tests/test_nav_slot.py +105 -0
  156. django_brickwork-1.0.0rc1/tests/test_nav_tag.py +237 -0
  157. django_brickwork-1.0.0rc1/tests/test_navigation.py +280 -0
  158. django_brickwork-1.0.0rc1/tests/test_patterns.py +229 -0
  159. django_brickwork-1.0.0rc1/tests/test_shell.py +170 -0
  160. django_brickwork-1.0.0rc1/tests/test_slide_over.py +169 -0
  161. django_brickwork-1.0.0rc1/tests/test_smoke.py +41 -0
  162. django_brickwork-1.0.0rc1/tests/test_stat.py +187 -0
  163. django_brickwork-1.0.0rc1/tests/test_stepper.py +124 -0
  164. django_brickwork-1.0.0rc1/tests/test_table_selection.py +207 -0
  165. django_brickwork-1.0.0rc1/tests/test_tabs.py +205 -0
  166. django_brickwork-1.0.0rc1/tests/test_tailwind_projection.py +176 -0
  167. django_brickwork-1.0.0rc1/tests/test_theme.py +63 -0
  168. django_brickwork-1.0.0rc1/tests/test_tiers.py +123 -0
  169. django_brickwork-1.0.0rc1/tests/test_toast.py +203 -0
  170. django_brickwork-1.0.0rc1/tests/test_token_derivations.py +204 -0
  171. django_brickwork-1.0.0rc1/tests/test_token_manifest.py +125 -0
  172. django_brickwork-1.0.0rc1/tests/test_tokens.py +261 -0
  173. django_brickwork-1.0.0rc1/tests/test_wizard.py +105 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nigel Copley
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,62 @@
1
+ django-brickwork
2
+ Copyright (c) 2026 Nigel Copley
3
+
4
+ This product is licensed under the MIT License (see LICENSE).
5
+
6
+ It includes third-party material under the terms below. These notices cover the
7
+ vendored icon artwork seeded into the brickwork icon registry
8
+ (src/brickwork/icons/vendor/). The icon *names* are brickwork's own versioned
9
+ public contract; the vendored artwork is a pinned, swappable implementation
10
+ detail behind those names.
11
+
12
+ --------------------------------------------------------------------------------
13
+ Lucide (https://lucide.dev)
14
+ --------------------------------------------------------------------------------
15
+
16
+ The curated icon subset in src/brickwork/icons/vendor/lucide/ is taken from the
17
+ `lucide-static` package (v1.28.0) and is used under the ISC License.
18
+
19
+ ISC License
20
+
21
+ Copyright (c) 2020, Lucide Contributors
22
+
23
+ Permission to use, copy, modify, and/or distribute this software for any
24
+ purpose with or without fee is hereby granted, provided that the above
25
+ copyright notice and this permission notice appear in all copies.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
28
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
29
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
30
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
31
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
32
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
33
+ PERFORMANCE OF THIS SOFTWARE.
34
+
35
+ --------------------------------------------------------------------------------
36
+ Feather (https://feathericons.com)
37
+ --------------------------------------------------------------------------------
38
+
39
+ A subset of the Lucide icons above derive from Feather, which is distributed
40
+ under the MIT License. That subset is therefore additionally covered by:
41
+
42
+ The MIT License (MIT)
43
+
44
+ Copyright (c) 2013-2023 Cole Bemis
45
+
46
+ Permission is hereby granted, free of charge, to any person obtaining a copy
47
+ of this software and associated documentation files (the "Software"), to deal
48
+ in the Software without restriction, including without limitation the rights
49
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
50
+ copies of the Software, and to permit persons to whom the Software is
51
+ furnished to do so, subject to the following conditions:
52
+
53
+ The above copyright notice and this permission notice shall be included in all
54
+ copies or substantial portions of the Software.
55
+
56
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
60
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
61
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
62
+ SOFTWARE.
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-brickwork
3
+ Version: 1.0.0rc1
4
+ Summary: Brand-agnostic, app-facing professional UI substrate for server-rendered Django (Tailwind 4, Alpine 3, HTMX 2). Accessible by construction; not a Django-admin skin.
5
+ Author: Nigel Copley
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/icvoss/django-brickwork
8
+ Project-URL: Documentation, https://github.com/icvoss/django-brickwork
9
+ Project-URL: Changelog, https://github.com/icvoss/django-brickwork/blob/main/CHANGELOG.md
10
+ Project-URL: Issue Tracker, https://github.com/icvoss/django-brickwork/issues
11
+ Project-URL: Source Code, https://github.com/icvoss/django-brickwork
12
+ Keywords: django,ui,design-system,tailwind,alpine,htmx,accessibility,wcag,components
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Web Environment
15
+ Classifier: Framework :: Django
16
+ Classifier: Framework :: Django :: 6.0
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: User Interfaces
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ License-File: NOTICE
25
+ Requires-Dist: Django>=6.0
26
+ Provides-Extra: htmx
27
+ Requires-Dist: django-htmx>=1.28; extra == "htmx"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Requires-Dist: pytest-django>=4.8; extra == "dev"
31
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
32
+ Requires-Dist: django-htmx>=1.28; extra == "dev"
33
+ Requires-Dist: ruff>=0.5.0; extra == "dev"
34
+ Requires-Dist: mypy>=1.10; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # brickwork
38
+
39
+ A brand-agnostic, app-facing professional UI substrate for server-rendered
40
+ Django, on the ecosystem stack: Tailwind 4 (CSS-first), Alpine 3, HTMX 2,
41
+ Django 6.0. It provides the application shell, navigation and active-route
42
+ resolution, an accessible form-field renderer, and interaction primitives
43
+ (modal, toast, dropdown, combobox, tabs, disclosure) wrapped behind stable
44
+ Django components.
45
+
46
+ **This is not a Django-admin skin.** Its value is the professional baseline:
47
+ WCAG 2.2 AA as a *tested* guarantee (axe-core in CI, not a claim), RTL via
48
+ logical properties, a real themeable dark-mode system, and four composable
49
+ theme axes (brand x theme x density x direction). Applications provide data,
50
+ permissions and business behaviour; the substrate provides structure,
51
+ presentation and interaction conventions.
52
+
53
+ > Status: **0.16.0, graduating to public PyPI.** The five semver-governed
54
+ > public-API contracts (token, template, navigation, interaction, JavaScript)
55
+ > are live, and every component passes two hard gates: is it accessible
56
+ > (axe-core WCAG 2.2 AA in CI) and is it beautiful by default. The surface is
57
+ > complete: the application shell and nav, the beautiful-by-default token system
58
+ > (elevation, state overlays, type roles, motion, borders, with fine colours
59
+ > derived live from a small load-bearing brand set via `color-mix()`), the
60
+ > interaction set (modal, toast, dropdown, combobox, tabs, disclosure, tooltip,
61
+ > slide-over), forms with the whole-form renderer and the HTMX 422 loop, the
62
+ > data table with sortable and selectable modes, the feedback and input-chrome
63
+ > primitives, the wizard/stepper, and a machine-readable token contract with a
64
+ > per-tenant brand-CSS emitter. The design of record is the spec and brief in
65
+ > the icvoss/oss umbrella:
66
+ > - Spec: `docs/specs/django-brickwork/` (the five versioned public-API contracts).
67
+ > - Design + branding + integration: `docs/DESIGN.md`, `docs/BRANDING.md`,
68
+ > `docs/INTEGRATION.md`, `docs/ADOPTION.md`.
69
+ > - Changelog: `CHANGELOG.md` (0.1.0 through 0.16.0).
70
+
71
+ ## Documentation
72
+
73
+ - [docs/DESIGN.md](docs/DESIGN.md): the canonical token reference; every
74
+ `--bw-*` name, default value, and derivation rule.
75
+ - [docs/BRANDING.md](docs/BRANDING.md): how a consuming app brands brickwork
76
+ (the load-bearing token minimum, dark mode, the four axes, the fg-on-accent
77
+ contrast trap, and dynamic per-tenant / per-user theming recipes).
78
+ - [docs/INTEGRATION.md](docs/INTEGRATION.md): the greenfield integration
79
+ cookbook, the seams a consuming app wires end to end (settings and static, nav
80
+ config, context processor, a worked HTMX 422 form, the chrome/body boundary).
81
+ - [docs/ADOPTION.md](docs/ADOPTION.md): the strangle guide for migrating an
82
+ existing app onto brickwork cluster by cluster (multi-host, asset coexistence,
83
+ the htmx floor).
84
+ - [frontend/README.md](frontend/README.md): the in-repo build that compiles
85
+ the shipped static assets.
86
+
87
+ ## Install
88
+
89
+ ```
90
+ pip install django-brickwork # from pypi.icvoss.com (private index)
91
+ ```
92
+
93
+ ```python
94
+ INSTALLED_APPS = [
95
+ "brickwork",
96
+ # ...
97
+ ]
98
+ ```
99
+
100
+ The compiled CSS and JS ship inside the package and are referenced with plain
101
+ `{% static %}`; no build-tool dependency (django-vite / django-tailwind) is
102
+ imposed on consumers. Consumers provide their own Alpine 3 +
103
+ `@alpinejs/focus` (and optionally htmx 2) via their own frontend build; brickwork
104
+ registers behaviour onto the host Alpine instance and never calls
105
+ `Alpine.start()`.
106
+
107
+ ### htmx floor: htmx >= 2.0
108
+
109
+ brickwork's interaction contracts (the HTMX 422 form-swap loop, toast delivery
110
+ via `hx-swap-oob`, modal dismissal via the `HX-Trigger: bw:modal:close` response
111
+ header, combobox server filtering) are built and CI-gated on **htmx >= 2.0**
112
+ only. htmx 1.9 is out of contract (BR-BW-HTMX-010): htmx 2 changed default
113
+ response handling in ways the 422 loop relies on, and the interaction suites only
114
+ ever exercise htmx 2. A brownfield app on htmx 1.9 should upgrade htmx to 2.x as a
115
+ prerequisite before adopting brickwork's interaction primitives; see
116
+ [docs/ADOPTION.md](docs/ADOPTION.md).
117
+
118
+ ## Contracts
119
+
120
+ brickwork's public API is five versioned contracts (see the spec): **token**,
121
+ **template**, **navigation**, **interaction (HTMX)**, and **JavaScript
122
+ (Alpine)**. Template block names, HTMX target IDs, Alpine component names,
123
+ event names and token names are semver-governed.
124
+
125
+ ## Usage
126
+
127
+ ### Tags vs includes
128
+
129
+ Some components are consumed as **template tags**, others via `{% include %}`.
130
+ This is deliberate: a component that carries logic (variant validation, a11y
131
+ enforcement, icon resolution) ships as a tag so that logic is not duplicated at
132
+ every call site; a purely structural component is an include the consumer fills
133
+ with context.
134
+
135
+ - **Tags** (load the library first): `{% bw_icon %}`, `{% bw_button %}`,
136
+ `{% bw_badge %}`, `{% bw_alert %}`, `{% bw_nav %}`, `{% bw_field_widget %}`.
137
+
138
+ ```django
139
+ {% load brickwork_components brickwork_icons brickwork_nav %}
140
+ {% bw_button label="Save" variant="primary" %}
141
+ {% bw_badge label="New" variant="info" %}
142
+ ```
143
+
144
+ The `_button.html` / `_badge.html` / `_alert.html` template files exist but are
145
+ the tags' own render targets, **not** a consumer-facing `{% include %}` API.
146
+ Call the tag, not the partial.
147
+
148
+ - **Includes** (structure you fill with context): `_page_header.html`,
149
+ `_data_table.html`, `_pagination.html`, `_empty_state.html`,
150
+ `_filter_bar.html`, `_spinner.html`, and the form partials `forms/_field.html`
151
+ / `forms/_form_errors.html`.
152
+
153
+ ```django
154
+ {% include "brickwork/components/_data_table.html" with table_id="gadgets" columns=columns rows=rows %}
155
+ ```
156
+
157
+ ### Icons: decorative or labelled, always
158
+
159
+ `{% bw_icon %}` **requires** exactly one of `decorative=True` or `label="..."`,
160
+ and raises `TemplateSyntaxError` if given neither or both. This is intentional
161
+ (ICO-007, WCAG 4.1.2): an icon is either purely presentational (aria-hidden) or
162
+ carries meaning (an accessible name), never ambiguous.
163
+
164
+ ```django
165
+ {% bw_icon "search" decorative=True %} {# beside a visible label #}
166
+ {% bw_icon "trash" label="Delete item" %} {# standalone, meaningful #}
167
+ ```
168
+
169
+ You rarely call `bw_icon` directly for the icon *inside* a `bw_button` or
170
+ `bw_nav` item: those tags take an `icon="..."` argument and handle the a11y
171
+ pairing for you. Reach for `bw_icon` directly only for a standalone icon in your
172
+ own markup, where this rule applies.
173
+
174
+ ## Development
175
+
176
+ Python package:
177
+
178
+ ```
179
+ pip install -e ".[dev]"
180
+ pytest
181
+ ```
182
+
183
+ Frontend build (compiles tokens + component assets into the package's static
184
+ dir; see `frontend/README.md`):
185
+
186
+ ```
187
+ npm install
188
+ npm run build
189
+ ```
190
+
191
+ ## Licence
192
+
193
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,157 @@
1
+ # brickwork
2
+
3
+ A brand-agnostic, app-facing professional UI substrate for server-rendered
4
+ Django, on the ecosystem stack: Tailwind 4 (CSS-first), Alpine 3, HTMX 2,
5
+ Django 6.0. It provides the application shell, navigation and active-route
6
+ resolution, an accessible form-field renderer, and interaction primitives
7
+ (modal, toast, dropdown, combobox, tabs, disclosure) wrapped behind stable
8
+ Django components.
9
+
10
+ **This is not a Django-admin skin.** Its value is the professional baseline:
11
+ WCAG 2.2 AA as a *tested* guarantee (axe-core in CI, not a claim), RTL via
12
+ logical properties, a real themeable dark-mode system, and four composable
13
+ theme axes (brand x theme x density x direction). Applications provide data,
14
+ permissions and business behaviour; the substrate provides structure,
15
+ presentation and interaction conventions.
16
+
17
+ > Status: **0.16.0, graduating to public PyPI.** The five semver-governed
18
+ > public-API contracts (token, template, navigation, interaction, JavaScript)
19
+ > are live, and every component passes two hard gates: is it accessible
20
+ > (axe-core WCAG 2.2 AA in CI) and is it beautiful by default. The surface is
21
+ > complete: the application shell and nav, the beautiful-by-default token system
22
+ > (elevation, state overlays, type roles, motion, borders, with fine colours
23
+ > derived live from a small load-bearing brand set via `color-mix()`), the
24
+ > interaction set (modal, toast, dropdown, combobox, tabs, disclosure, tooltip,
25
+ > slide-over), forms with the whole-form renderer and the HTMX 422 loop, the
26
+ > data table with sortable and selectable modes, the feedback and input-chrome
27
+ > primitives, the wizard/stepper, and a machine-readable token contract with a
28
+ > per-tenant brand-CSS emitter. The design of record is the spec and brief in
29
+ > the icvoss/oss umbrella:
30
+ > - Spec: `docs/specs/django-brickwork/` (the five versioned public-API contracts).
31
+ > - Design + branding + integration: `docs/DESIGN.md`, `docs/BRANDING.md`,
32
+ > `docs/INTEGRATION.md`, `docs/ADOPTION.md`.
33
+ > - Changelog: `CHANGELOG.md` (0.1.0 through 0.16.0).
34
+
35
+ ## Documentation
36
+
37
+ - [docs/DESIGN.md](docs/DESIGN.md): the canonical token reference; every
38
+ `--bw-*` name, default value, and derivation rule.
39
+ - [docs/BRANDING.md](docs/BRANDING.md): how a consuming app brands brickwork
40
+ (the load-bearing token minimum, dark mode, the four axes, the fg-on-accent
41
+ contrast trap, and dynamic per-tenant / per-user theming recipes).
42
+ - [docs/INTEGRATION.md](docs/INTEGRATION.md): the greenfield integration
43
+ cookbook, the seams a consuming app wires end to end (settings and static, nav
44
+ config, context processor, a worked HTMX 422 form, the chrome/body boundary).
45
+ - [docs/ADOPTION.md](docs/ADOPTION.md): the strangle guide for migrating an
46
+ existing app onto brickwork cluster by cluster (multi-host, asset coexistence,
47
+ the htmx floor).
48
+ - [frontend/README.md](frontend/README.md): the in-repo build that compiles
49
+ the shipped static assets.
50
+
51
+ ## Install
52
+
53
+ ```
54
+ pip install django-brickwork # from pypi.icvoss.com (private index)
55
+ ```
56
+
57
+ ```python
58
+ INSTALLED_APPS = [
59
+ "brickwork",
60
+ # ...
61
+ ]
62
+ ```
63
+
64
+ The compiled CSS and JS ship inside the package and are referenced with plain
65
+ `{% static %}`; no build-tool dependency (django-vite / django-tailwind) is
66
+ imposed on consumers. Consumers provide their own Alpine 3 +
67
+ `@alpinejs/focus` (and optionally htmx 2) via their own frontend build; brickwork
68
+ registers behaviour onto the host Alpine instance and never calls
69
+ `Alpine.start()`.
70
+
71
+ ### htmx floor: htmx >= 2.0
72
+
73
+ brickwork's interaction contracts (the HTMX 422 form-swap loop, toast delivery
74
+ via `hx-swap-oob`, modal dismissal via the `HX-Trigger: bw:modal:close` response
75
+ header, combobox server filtering) are built and CI-gated on **htmx >= 2.0**
76
+ only. htmx 1.9 is out of contract (BR-BW-HTMX-010): htmx 2 changed default
77
+ response handling in ways the 422 loop relies on, and the interaction suites only
78
+ ever exercise htmx 2. A brownfield app on htmx 1.9 should upgrade htmx to 2.x as a
79
+ prerequisite before adopting brickwork's interaction primitives; see
80
+ [docs/ADOPTION.md](docs/ADOPTION.md).
81
+
82
+ ## Contracts
83
+
84
+ brickwork's public API is five versioned contracts (see the spec): **token**,
85
+ **template**, **navigation**, **interaction (HTMX)**, and **JavaScript
86
+ (Alpine)**. Template block names, HTMX target IDs, Alpine component names,
87
+ event names and token names are semver-governed.
88
+
89
+ ## Usage
90
+
91
+ ### Tags vs includes
92
+
93
+ Some components are consumed as **template tags**, others via `{% include %}`.
94
+ This is deliberate: a component that carries logic (variant validation, a11y
95
+ enforcement, icon resolution) ships as a tag so that logic is not duplicated at
96
+ every call site; a purely structural component is an include the consumer fills
97
+ with context.
98
+
99
+ - **Tags** (load the library first): `{% bw_icon %}`, `{% bw_button %}`,
100
+ `{% bw_badge %}`, `{% bw_alert %}`, `{% bw_nav %}`, `{% bw_field_widget %}`.
101
+
102
+ ```django
103
+ {% load brickwork_components brickwork_icons brickwork_nav %}
104
+ {% bw_button label="Save" variant="primary" %}
105
+ {% bw_badge label="New" variant="info" %}
106
+ ```
107
+
108
+ The `_button.html` / `_badge.html` / `_alert.html` template files exist but are
109
+ the tags' own render targets, **not** a consumer-facing `{% include %}` API.
110
+ Call the tag, not the partial.
111
+
112
+ - **Includes** (structure you fill with context): `_page_header.html`,
113
+ `_data_table.html`, `_pagination.html`, `_empty_state.html`,
114
+ `_filter_bar.html`, `_spinner.html`, and the form partials `forms/_field.html`
115
+ / `forms/_form_errors.html`.
116
+
117
+ ```django
118
+ {% include "brickwork/components/_data_table.html" with table_id="gadgets" columns=columns rows=rows %}
119
+ ```
120
+
121
+ ### Icons: decorative or labelled, always
122
+
123
+ `{% bw_icon %}` **requires** exactly one of `decorative=True` or `label="..."`,
124
+ and raises `TemplateSyntaxError` if given neither or both. This is intentional
125
+ (ICO-007, WCAG 4.1.2): an icon is either purely presentational (aria-hidden) or
126
+ carries meaning (an accessible name), never ambiguous.
127
+
128
+ ```django
129
+ {% bw_icon "search" decorative=True %} {# beside a visible label #}
130
+ {% bw_icon "trash" label="Delete item" %} {# standalone, meaningful #}
131
+ ```
132
+
133
+ You rarely call `bw_icon` directly for the icon *inside* a `bw_button` or
134
+ `bw_nav` item: those tags take an `icon="..."` argument and handle the a11y
135
+ pairing for you. Reach for `bw_icon` directly only for a standalone icon in your
136
+ own markup, where this rule applies.
137
+
138
+ ## Development
139
+
140
+ Python package:
141
+
142
+ ```
143
+ pip install -e ".[dev]"
144
+ pytest
145
+ ```
146
+
147
+ Frontend build (compiles tokens + component assets into the package's static
148
+ dir; see `frontend/README.md`):
149
+
150
+ ```
151
+ npm install
152
+ npm run build
153
+ ```
154
+
155
+ ## Licence
156
+
157
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,128 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "django-brickwork"
7
+ version = "1.0.0rc1"
8
+ description = "Brand-agnostic, app-facing professional UI substrate for server-rendered Django (Tailwind 4, Alpine 3, HTMX 2). Accessible by construction; not a Django-admin skin."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.12"
12
+ authors = [{name = "Nigel Copley"}]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Environment :: Web Environment",
16
+ "Framework :: Django",
17
+ "Framework :: Django :: 6.0",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Topic :: Software Development :: User Interfaces",
22
+ ]
23
+ keywords = [
24
+ "django",
25
+ "ui",
26
+ "design-system",
27
+ "tailwind",
28
+ "alpine",
29
+ "htmx",
30
+ "accessibility",
31
+ "wcag",
32
+ "components",
33
+ ]
34
+ # Django 6.0 floor: the package uses core template partials
35
+ # ({% partialdef %} / render(request, "t#partial")) with no compat shim.
36
+ #
37
+ # Django is the ONLY hard runtime dependency. Deliberately NOT depended on
38
+ # (build-tool research 2026-07-30, a library inherits every dep five times):
39
+ # - django-htmx: brickwork's own need is one boolean (HX-Request header). It
40
+ # inlines that check and duck-types request.htmx when a consumer already
41
+ # runs django-htmx. Offered as the optional [htmx] extra, never forced.
42
+ # - django-vite: unnecessary. brickwork ships STABLE (non-hashed) asset
43
+ # filenames referenced by plain {% static %}; there is no Vite manifest to
44
+ # resolve. (Also stale: no Django 5.x/6.x support.)
45
+ # - django-tailwind / -cli: irrelevant. They manage a Tailwind build inside a
46
+ # live Django project; brickwork compiles its CSS in its OWN repo (Vite +
47
+ # @tailwindcss/vite) and ships the precompiled artefact.
48
+ # Tailwind/Alpine/HTMX are FRONTEND runtime (loaded via <link>/<script> against
49
+ # the shipped static assets), not Python packages. @alpinejs/ui + @alpinejs/focus
50
+ # are host-owned peer deps delivered by the consumer's own Vite/npm build.
51
+ dependencies = [
52
+ "Django>=6.0",
53
+ ]
54
+
55
+ [project.urls]
56
+ Homepage = "https://github.com/icvoss/django-brickwork"
57
+ Documentation = "https://github.com/icvoss/django-brickwork"
58
+ Changelog = "https://github.com/icvoss/django-brickwork/blob/main/CHANGELOG.md"
59
+ "Issue Tracker" = "https://github.com/icvoss/django-brickwork/issues"
60
+ "Source Code" = "https://github.com/icvoss/django-brickwork"
61
+
62
+ [project.optional-dependencies]
63
+ # Optional: consumers already running django-htmx get brickwork's HTMX-aware
64
+ # helpers using the richer request.htmx surface. brickwork's core never imports
65
+ # it (it inlines the HX-Request header check + duck-types request.htmx), so
66
+ # consumers without this extra are unaffected.
67
+ htmx = ["django-htmx>=1.28"]
68
+ dev = [
69
+ "pytest>=8.0",
70
+ "pytest-django>=4.8",
71
+ "pytest-cov>=5.0",
72
+ "django-htmx>=1.28",
73
+ "ruff>=0.5.0",
74
+ "mypy>=1.10",
75
+ ]
76
+
77
+ [tool.setuptools.packages.find]
78
+ where = ["src"]
79
+
80
+ [tool.setuptools.package-data]
81
+ # Ship templates, the compiled CSS/JS/token artefacts (built by the frontend
82
+ # pipeline into static/brickwork/dist), the vendored icon artwork the registry
83
+ # loads at import, the DTCG token source, and the PEP 561 typed marker.
84
+ brickwork = [
85
+ "py.typed",
86
+ "templates/**/*.html",
87
+ "static/**/*",
88
+ "icons/vendor/**/*.svg",
89
+ "tokens/source/**/*.json",
90
+ ]
91
+
92
+ [tool.pytest.ini_options]
93
+ DJANGO_SETTINGS_MODULE = "tests.settings"
94
+ # "." (repo root) so `tests.settings` resolves as a package; "src" for the
95
+ # package. NOT "tests" itself: that would put tests/'s contents at top level and
96
+ # shadow the `tests` package, breaking the `tests.settings` import (CI-caught).
97
+ # The seams leg additionally needs `brickwork_testapp` importable; its CI step
98
+ # and the a11y fixtures set PYTHONPATH=src:.:tests for that.
99
+ pythonpath = ["src", "."]
100
+ testpaths = ["tests"]
101
+
102
+ [tool.ruff]
103
+ target-version = "py312"
104
+ line-length = 120
105
+ src = ["src"]
106
+
107
+ [tool.ruff.lint]
108
+ select = ["E", "W", "F", "I", "B", "UP", "N", "SIM"]
109
+ ignore = ["E501", "SIM105"]
110
+
111
+ [tool.ruff.lint.isort]
112
+ known-first-party = ["brickwork"]
113
+
114
+ [tool.ruff.format]
115
+ quote-style = "double"
116
+
117
+ [tool.mypy]
118
+ python_version = "3.12"
119
+ strict = false
120
+
121
+ [tool.coverage.run]
122
+ source = ["src"]
123
+ omit = ["*/tests/*"]
124
+
125
+ [tool.coverage.report]
126
+ fail_under = 90
127
+ show_missing = true
128
+ exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:", "if __name__ =="]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,20 @@
1
+ """brickwork: a brand-agnostic, app-facing professional UI substrate for Django.
2
+
3
+ Provides the application shell, navigation and active-route resolution, an
4
+ accessible form-field renderer, and interaction primitives (modal, toast,
5
+ dropdown, combobox, tabs, disclosure) wrapped behind stable Django components,
6
+ on the ecosystem stack (Tailwind 4 CSS-first, Alpine 3, HTMX 2, Django 6.0).
7
+
8
+ This is NOT a Django-admin skin. Its value is the professional baseline:
9
+ WCAG 2.2 AA as a tested guarantee, RTL via logical properties, a real themeable
10
+ dark-mode system, and four composable theme axes (brand x theme x density x
11
+ direction). See docs/specs/django-brickwork/ in the icvoss/oss umbrella for the five
12
+ versioned public-API contracts (token, template, navigation, interaction,
13
+ JavaScript).
14
+
15
+ The design-token layer lives in the framework-neutral ``brickwork.tokens``
16
+ sub-module; a separate ``brickwork_tokens`` package is deferred until a
17
+ non-Django consumer earns the split.
18
+ """
19
+
20
+ __version__ = "1.0.0rc1"
@@ -0,0 +1,25 @@
1
+ """Django app configuration for brickwork.
2
+
3
+ The ``AppConfig.ready()`` hook is where any system checks for the token/template
4
+ contracts are registered. Navigation duplicate-key validation is enforced by the
5
+ consuming project calling ``validate_nav_config()`` at import time
6
+ (BR-BW-NAV-002), not from ``ready()``, since brickwork ships no nav config of its
7
+ own. Kept minimal in the scaffold; populated as the check subsystem lands in
8
+ Phase 0.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from django.apps import AppConfig
14
+
15
+
16
+ class BrickworkConfig(AppConfig):
17
+ name = "brickwork"
18
+ verbose_name = "brickwork UI substrate"
19
+ default_auto_field = "django.db.models.BigAutoField"
20
+
21
+ def ready(self) -> None:
22
+ # Phase 0: register system checks (token/template/nav contract guards)
23
+ # here. Intentionally empty until the check subsystem lands; an install
24
+ # imports cleanly with no models.
25
+ pass