django-bootstrap6-admin 0.2.0__tar.gz → 0.2.1__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 (72) hide show
  1. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/CHANGELOG.md +16 -0
  2. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/CONTRIBUTING.md +2 -2
  3. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/PKG-INFO +19 -7
  4. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/README.md +18 -6
  5. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/__init__.py +1 -1
  6. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/css/admin.css +98 -61
  7. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/base.html +52 -50
  8. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/login.html +0 -1
  9. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin.egg-info/PKG-INFO +19 -7
  10. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/test_admin_ui.py +2 -0
  11. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/test_package.py +3 -1
  12. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/LICENSE +0 -0
  13. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/MANIFEST.in +0 -0
  14. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/NOTICE +0 -0
  15. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/pyproject.toml +0 -0
  16. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/setup.cfg +0 -0
  17. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/apps.py +0 -0
  18. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/css/widgets-overrides.css +0 -0
  19. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/js/admin.js +0 -0
  20. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/js/theme.js +0 -0
  21. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/vendor/bootstrap/LICENSE +0 -0
  22. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/vendor/bootstrap/css/bootstrap.min.css +0 -0
  23. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/static/django_bootstrap6_admin/vendor/bootstrap/js/bootstrap.bundle.min.js +0 -0
  24. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/404.html +0 -0
  25. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/500.html +0 -0
  26. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/actions.html +0 -0
  27. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/app_index.html +0 -0
  28. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/app_list.html +0 -0
  29. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/auth/user/add_form.html +0 -0
  30. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/auth/user/change_password.html +0 -0
  31. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/base_site.html +0 -0
  32. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/change_form.html +0 -0
  33. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/change_form_object_tools.html +0 -0
  34. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/change_list.html +0 -0
  35. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/change_list_object_tools.html +0 -0
  36. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/change_list_results.html +0 -0
  37. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/color_theme_toggle.html +0 -0
  38. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/date_hierarchy.html +0 -0
  39. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/delete_confirmation.html +0 -0
  40. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/delete_selected_confirmation.html +0 -0
  41. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/edit_inline/stacked.html +0 -0
  42. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/edit_inline/tabular.html +0 -0
  43. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/filter.html +0 -0
  44. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/includes/fieldset.html +0 -0
  45. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/includes/object_delete_summary.html +0 -0
  46. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/index.html +0 -0
  47. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/nav_sidebar.html +0 -0
  48. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/object_history.html +0 -0
  49. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/pagination.html +0 -0
  50. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/search_form.html +0 -0
  51. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/submit_line.html +0 -0
  52. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/widgets/foreign_key_raw_id.html +0 -0
  53. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/admin/widgets/related_widget_wrapper.html +0 -0
  54. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/registration/logged_out.html +0 -0
  55. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/registration/password_change_done.html +0 -0
  56. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templates/registration/password_change_form.html +0 -0
  57. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templatetags/__init__.py +0 -0
  58. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin/templatetags/bootstrap6_admin.py +0 -0
  59. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin.egg-info/SOURCES.txt +0 -0
  60. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin.egg-info/dependency_links.txt +0 -0
  61. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin.egg-info/requires.txt +0 -0
  62. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/src/django_bootstrap6_admin.egg-info/top_level.txt +0 -0
  63. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/__init__.py +0 -0
  64. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/js/theme_toggle.test.js +0 -0
  65. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/settings.py +0 -0
  66. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/smoke_wheel.py +0 -0
  67. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/test_templatetags.py +0 -0
  68. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/testapp/__init__.py +0 -0
  69. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/testapp/admin.py +0 -0
  70. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/testapp/apps.py +0 -0
  71. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/testapp/models.py +0 -0
  72. {django_bootstrap6_admin-0.2.0 → django_bootstrap6_admin-0.2.1}/tests/urls.py +0 -0
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.1] - 2026-11-15
11
+
12
+ ### Added
13
+
14
+ - The "View site" link is now always visible in the admin top bar instead of
15
+ being hidden in the user menu.
16
+
17
+ ### Changed
18
+
19
+ - Refreshed the palette and surface treatment to match the warm near-black and
20
+ yellow visual language of the Pardus Teknofest project.
21
+ - Updated the login screen brand mark and browser theme colour to the new
22
+ palette.
23
+ - Documented that the admin follows Django's active language instead of being
24
+ hard-coded to English.
25
+
10
26
  ## [0.2.0] - 2026-11-15
11
27
 
12
28
  ### Added
@@ -71,8 +71,8 @@ environment and compiles every bundled template as a smoke test.
71
71
  5. Create and push an annotated tag:
72
72
 
73
73
  ```bash
74
- git tag -a v0.1.0 -m "django-bootstrap6-admin 0.1.0"
75
- git push origin v0.1.0
74
+ git tag -a v0.2.1 -m "django-bootstrap6-admin 0.2.1"
75
+ git push origin v0.2.1
76
76
  ```
77
77
 
78
78
  6. The `Release` workflow builds the distributions, verifies that the tag
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-bootstrap6-admin
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A modern Bootstrap 6 skin for the Django admin.
5
5
  Author-email: Aliberk Sandıkçı <git@asandikci.com>
6
6
  Maintainer-email: Aliberk Sandıkçı <git@asandikci.com>
@@ -53,6 +53,7 @@ permissions and JavaScript remain in charge.
53
53
  ## Features
54
54
 
55
55
  - Bootstrap 6 markup and design tokens throughout the admin.
56
+ - "View site" is always available in the top bar, not buried in the user menu.
56
57
  - Sticky top bar with a collapsible sidebar (desktop) and drawer navigation
57
58
  with a backdrop (mobile).
58
59
  - Dashboard with application cards, model shortcuts and recent activity.
@@ -81,8 +82,8 @@ permissions and JavaScript remain in charge.
81
82
  - CSP-aware: bundled scripts and styles use Django 6.1's
82
83
  `{% csp_nonce_attr %}` tag, so nonce-based policies work out of the box.
83
84
  - Generic by design: no models, no migrations, no project-specific imports and
84
- no assumptions about the host project's branding. The default navy/gold
85
- palette is only a set of overridable CSS variables.
85
+ no assumptions about the host project's branding. The default warm
86
+ near-black/yellow palette is only a set of overridable CSS variables.
86
87
 
87
88
  ## Requirements
88
89
 
@@ -194,14 +195,15 @@ custom admin CSS file:
194
195
 
195
196
  ```css
196
197
  :root {
197
- --ba-topbar-bg: #1f2937;
198
- --ba-gold: #f59e0b;
198
+ --ba-topbar-bg: #231f20;
199
+ --ba-gold: #ffcb08;
200
+ --ba-canvas: #f6f6f4;
199
201
  --ba-sidebar-width: 300px;
200
202
  }
201
203
  ```
202
204
 
203
- The default primary and danger colours are deliberately deeper than Bootstrap
204
- 6's defaults so white button text meets WCAG AA contrast.
205
+ The default primary is the warm yellow accent with dark text, and the danger
206
+ colour remains a deep red for readable white labels.
205
207
 
206
208
  The select controls use small `data:` SVG arrows. If you enable a strict CSP,
207
209
  allow `img-src 'self' data:` (or replace the arrows in your own CSS).
@@ -229,6 +231,16 @@ There is no runtime state to clean up.
229
231
  - `bootstrap.bundle.min.js`:
230
232
  `47ea447f46e288dd9d3e83147b7ba539c6df5192c047b8f91739cd56a5721148`
231
233
 
234
+ ### Language
235
+
236
+ Django's admin is translated using the active language; it is not fixed to
237
+ English. With `LANGUAGE_CODE = "tr"`, Django's own admin labels are Turkish,
238
+ and this theme follows the same project language. The package's source strings
239
+ are English and are translated when a matching locale is installed. To keep
240
+ the admin in English while the public site uses another language, activate
241
+ English for `/admin/` in your project (for example with a small middleware),
242
+ or set `LANGUAGE_CODE = "en-us"` if the whole site should be English.
243
+
232
244
  ## Development
233
245
 
234
246
  The test suite uses an isolated settings module and a small demo app. Create a
@@ -16,6 +16,7 @@ permissions and JavaScript remain in charge.
16
16
  ## Features
17
17
 
18
18
  - Bootstrap 6 markup and design tokens throughout the admin.
19
+ - "View site" is always available in the top bar, not buried in the user menu.
19
20
  - Sticky top bar with a collapsible sidebar (desktop) and drawer navigation
20
21
  with a backdrop (mobile).
21
22
  - Dashboard with application cards, model shortcuts and recent activity.
@@ -44,8 +45,8 @@ permissions and JavaScript remain in charge.
44
45
  - CSP-aware: bundled scripts and styles use Django 6.1's
45
46
  `{% csp_nonce_attr %}` tag, so nonce-based policies work out of the box.
46
47
  - Generic by design: no models, no migrations, no project-specific imports and
47
- no assumptions about the host project's branding. The default navy/gold
48
- palette is only a set of overridable CSS variables.
48
+ no assumptions about the host project's branding. The default warm
49
+ near-black/yellow palette is only a set of overridable CSS variables.
49
50
 
50
51
  ## Requirements
51
52
 
@@ -157,14 +158,15 @@ custom admin CSS file:
157
158
 
158
159
  ```css
159
160
  :root {
160
- --ba-topbar-bg: #1f2937;
161
- --ba-gold: #f59e0b;
161
+ --ba-topbar-bg: #231f20;
162
+ --ba-gold: #ffcb08;
163
+ --ba-canvas: #f6f6f4;
162
164
  --ba-sidebar-width: 300px;
163
165
  }
164
166
  ```
165
167
 
166
- The default primary and danger colours are deliberately deeper than Bootstrap
167
- 6's defaults so white button text meets WCAG AA contrast.
168
+ The default primary is the warm yellow accent with dark text, and the danger
169
+ colour remains a deep red for readable white labels.
168
170
 
169
171
  The select controls use small `data:` SVG arrows. If you enable a strict CSP,
170
172
  allow `img-src 'self' data:` (or replace the arrows in your own CSS).
@@ -192,6 +194,16 @@ There is no runtime state to clean up.
192
194
  - `bootstrap.bundle.min.js`:
193
195
  `47ea447f46e288dd9d3e83147b7ba539c6df5192c047b8f91739cd56a5721148`
194
196
 
197
+ ### Language
198
+
199
+ Django's admin is translated using the active language; it is not fixed to
200
+ English. With `LANGUAGE_CODE = "tr"`, Django's own admin labels are Turkish,
201
+ and this theme follows the same project language. The package's source strings
202
+ are English and are translated when a matching locale is installed. To keep
203
+ the admin in English while the public site uses another language, activate
204
+ English for `/admin/` in your project (for example with a small middleware),
205
+ or set `LANGUAGE_CODE = "en-us"` if the whole site should be English.
206
+
195
207
  ## Development
196
208
 
197
209
  The test suite uses an isolated settings module and a small demo app. Create a
@@ -1,3 +1,3 @@
1
1
  """Bootstrap 6 skin for the Django admin."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.2.1"
@@ -12,42 +12,45 @@
12
12
  --ba-sidebar-width: 272px;
13
13
  --ba-content-max: 1600px;
14
14
 
15
- --ba-topbar-bg: light-dark(#172b45, #0c1520);
16
- --ba-topbar-fg: light-dark(#f3f7fb, #e5edf6);
17
- --ba-topbar-muted: light-dark(#aebed0, #9fb0c2);
18
- --ba-canvas: light-dark(#f4f6f9, #0d141c);
19
- --ba-surface: light-dark(#ffffff, #151f2b);
20
- --ba-surface-muted: light-dark(#f8fafc, #111a24);
21
- --ba-border: light-dark(#dce3eb, #2d3a4b);
22
- --ba-border-strong: light-dark(#c6d0dc, #3b4b5f);
23
- --ba-gold: light-dark(#c99b54, #d6b46f);
24
- --ba-shadow-sm: 0 1px 2px rgb(23 43 69 / 0.06);
25
- --ba-shadow-md: 0 0.5rem 1.5rem rgb(23 43 69 / 0.08);
26
- --ba-shadow-lg: 0 1rem 3rem rgb(23 43 69 / 0.16);
27
- --ba-radius: var(--bs-radius-7);
28
- --ba-radius-sm: var(--bs-radius-5);
29
- --ba-text-muted: light-dark(#536274, #b3bfcd);
30
- --ba-control-border: light-dark(#7f8d9d, #6b7d91);
15
+ --ba-topbar-bg: light-dark(#231f20, #242122);
16
+ --ba-topbar-fg: light-dark(#f6f4f4, #f2efef);
17
+ --ba-topbar-muted: light-dark(#d8d3d2, #c6c0c0);
18
+ --ba-canvas: light-dark(#f6f6f4, #191718);
19
+ --ba-surface: light-dark(#ffffff, #222021);
20
+ --ba-surface-muted: light-dark(#fafaf8, #292627);
21
+ --ba-border: light-dark(#e3e3df, #3a3637);
22
+ --ba-border-strong: light-dark(#cfcfc8, #4a4546);
23
+ --ba-gold: light-dark(#ffcb08, #d8ab32);
24
+ --ba-shadow-sm: 0 1px 2px rgb(35 31 32 / 0.05);
25
+ --ba-shadow-md: 0 0.35rem 1rem rgb(35 31 32 / 0.07);
26
+ --ba-shadow-lg: 0 0.75rem 2rem rgb(35 31 32 / 0.12);
27
+ --ba-radius: 6px;
28
+ --ba-radius-sm: 4px;
29
+ --ba-text-muted: light-dark(#65605f, #c6c0c0);
30
+ --ba-control-border: light-dark(#b8b3ad, #6b6464);
31
31
 
32
32
  /*
33
- * Bootstrap 6's default primary is a very bright blue; white text on it
34
- * only reaches ~3.5:1. Use a deeper, accessible blue for light mode and a
35
- * slightly lighter one for dark mode.
33
+ * The Pardus Teknofest palette uses a warm near-black surface and a
34
+ * saturated yellow accent with dark text. Keep the primary role usable as
35
+ * an accent rather than a blue action colour.
36
36
  */
37
- --bs-primary-base: light-dark(#315e9b, #3f6ea8);
38
- --bs-primary-bg: light-dark(#315e9b, #3f6ea8);
39
- --bs-primary-contrast: #fff;
40
- --bs-primary-fg: light-dark(#244a7d, #a9c8ec);
41
- --bs-primary-fg-emphasis: light-dark(#1d3c66, #cfe1f7);
42
- --bs-primary-bg-subtle: light-dark(#eaf0f7, #23364b);
43
- --bs-primary-bg-muted: light-dark(#d9e4f1, #2f4a66);
44
- --bs-primary-border: light-dark(#6688b0, #6f95b8);
45
- --bs-secondary-border: light-dark(#8a97a6, #6b7d91);
37
+ --bs-primary-base: light-dark(#ffcb08, #d8ab32);
38
+ --bs-primary-bg: light-dark(#ffcb08, #d8ab32);
39
+ --bs-primary-contrast: #231f20;
40
+ --bs-primary-fg: light-dark(#7a5a00, #e8c66e);
41
+ --bs-primary-fg-emphasis: light-dark(#5f4600, #f3d98f);
42
+ --bs-primary-bg-subtle: light-dark(#fff6d6, #342c18);
43
+ --bs-primary-bg-muted: light-dark(#ffeaa1, #4a3d1e);
44
+ --bs-primary-border: light-dark(#d4a900, #8a6a19);
45
+ --bs-secondary-border: light-dark(#b8b3ad, #6b6464);
46
46
  --bs-primary-focus-ring: color-mix(
47
47
  in oklch,
48
- var(--bs-primary-bg) 55%,
49
- var(--bs-bg-body)
48
+ var(--bs-primary-bg) 45%,
49
+ transparent
50
50
  );
51
+ --bs-link-color: light-dark(#8a6500, #e8c66e);
52
+ --bs-link-hover-color: light-dark(#6f5000, #f3d98f);
53
+ --bs-border-muted: light-dark(#e3e3df, #3a3637);
51
54
 
52
55
  --bs-danger-base: light-dark(#b4233a, #c23a53);
53
56
  --bs-danger-bg: light-dark(#b4233a, #c23a53);
@@ -62,8 +65,8 @@
62
65
  var(--bs-danger-bg) 55%,
63
66
  var(--bs-bg-body)
64
67
  );
65
- --ba-select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23667085' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
66
- --ba-select-arrow-dark: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23aab6c5' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
68
+ --ba-select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%237a7472' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
69
+ --ba-select-arrow-dark: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23c6c0c0' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
67
70
 
68
71
  /* Django admin CSS variables used by widgets.css / autocomplete.css. */
69
72
  --primary: var(--bs-primary-bg);
@@ -118,14 +121,14 @@
118
121
  */
119
122
  [data-bs-theme="dark"],
120
123
  [data-effective-theme="dark"] {
121
- --bs-fg-1: #f1f5f9;
122
- --bs-fg-2: #d7e0ea;
123
- --bs-fg-3: #b9c7d6;
124
- --bs-fg-4: #9fb1c4;
125
- --ba-text-muted: #c9d4e0;
126
- --bs-link-color: #8dbcf7;
127
- --bs-link-hover-color: #b7d4ff;
128
- --bs-border-muted: #34465a;
124
+ --bs-fg-1: #f2efef;
125
+ --bs-fg-2: #dedada;
126
+ --bs-fg-3: #c6c0c0;
127
+ --bs-fg-4: #b0aaa9;
128
+ --ba-text-muted: #c6c0c0;
129
+ --bs-link-color: #e8c66e;
130
+ --bs-link-hover-color: #f3d98f;
131
+ --bs-border-muted: #3a3637;
129
132
  }
130
133
 
131
134
  html {
@@ -370,14 +373,9 @@ samp {
370
373
  inset-inline-start: 0;
371
374
  width: 100%;
372
375
  height: 3px;
373
- background: linear-gradient(
374
- 90deg,
375
- var(--ba-gold) 0,
376
- var(--ba-gold) 4.5rem,
377
- transparent 4.5rem
378
- );
376
+ background: var(--ba-gold);
379
377
  content: "";
380
- opacity: 0.9;
378
+ opacity: 1;
381
379
  pointer-events: none;
382
380
  }
383
381
 
@@ -438,13 +436,12 @@ samp {
438
436
  place-items: center;
439
437
  width: 2.35rem;
440
438
  height: 2.35rem;
441
- border-radius: 0.65rem;
442
- background: #fff;
443
- color: var(--ba-topbar-bg);
439
+ border-radius: var(--ba-radius-sm);
440
+ background: var(--ba-gold);
441
+ color: #231f20;
444
442
  font-size: 1.05rem;
445
443
  font-weight: 800;
446
444
  line-height: 1;
447
- box-shadow: 0 2px 0 rgb(0 0 0 / 0.12);
448
445
  }
449
446
 
450
447
  .ba-brand-text {
@@ -479,6 +476,32 @@ samp {
479
476
  margin-inline-start: auto;
480
477
  }
481
478
 
479
+ .ba-view-site {
480
+ --bs-btn-color: var(--ba-topbar-fg);
481
+ --bs-btn-bg: transparent;
482
+ --bs-btn-border-color: rgb(255 255 255 / 0.22);
483
+ --bs-btn-hover-bg: rgb(255 255 255 / 0.1);
484
+ --bs-btn-hover-color: #fff;
485
+ --bs-btn-hover-border-color: rgb(255 255 255 / 0.38);
486
+ --bs-btn-active-bg: rgb(255 255 255 / 0.16);
487
+ --bs-btn-active-color: #fff;
488
+ display: inline-flex;
489
+ align-items: center;
490
+ justify-content: center;
491
+ gap: 0.35rem;
492
+ min-height: 2.35rem;
493
+ padding: 0.25rem 0.7rem;
494
+ border-radius: var(--ba-radius-sm);
495
+ font-size: 0.8rem;
496
+ font-weight: 600;
497
+ white-space: nowrap;
498
+ }
499
+
500
+ .ba-view-site .ba-icon {
501
+ width: 0.9rem;
502
+ height: 0.9rem;
503
+ }
504
+
482
505
  .ba-theme-toggle {
483
506
  --bs-btn-color: var(--ba-topbar-fg);
484
507
  --bs-btn-bg: transparent;
@@ -490,7 +513,7 @@ samp {
490
513
  --bs-btn-active-color: #fff;
491
514
  width: 2.35rem;
492
515
  height: 2.35rem;
493
- border-radius: 50%;
516
+ border-radius: var(--ba-radius-sm);
494
517
  }
495
518
 
496
519
  #branding > .ba-theme-toggle {
@@ -539,7 +562,7 @@ html[data-effective-theme="dark"] .theme-icon-when-dark {
539
562
  --bs-btn-active-color: #fff;
540
563
  min-height: 2.35rem;
541
564
  padding: 0.25rem 0.55rem 0.25rem 0.3rem;
542
- border-radius: 999px;
565
+ border-radius: var(--ba-radius-sm);
543
566
  }
544
567
 
545
568
  .ba-user-avatar {
@@ -550,7 +573,7 @@ html[data-effective-theme="dark"] .theme-icon-when-dark {
550
573
  height: 1.8rem;
551
574
  border-radius: 50%;
552
575
  background: var(--ba-gold);
553
- color: #172b45;
576
+ color: #231f20;
554
577
  font-size: 0.78rem;
555
578
  font-weight: 800;
556
579
  }
@@ -1635,7 +1658,8 @@ a.ba-date-chip:focus {
1635
1658
  background-size: 0.65rem;
1636
1659
  }
1637
1660
 
1638
- [data-bs-theme="dark"] #result_list select {
1661
+ [data-bs-theme="dark"] #result_list select,
1662
+ [data-effective-theme="dark"] #result_list select {
1639
1663
  background-image: var(--ba-select-arrow-dark);
1640
1664
  }
1641
1665
 
@@ -2218,7 +2242,10 @@ label.required::after {
2218
2242
 
2219
2243
  [data-bs-theme="dark"] .ba-field select,
2220
2244
  [data-bs-theme="dark"] .ba-form-group select,
2221
- [data-bs-theme="dark"] .ba-actions select {
2245
+ [data-bs-theme="dark"] .ba-actions select,
2246
+ [data-effective-theme="dark"] .ba-field select,
2247
+ [data-effective-theme="dark"] .ba-form-group select,
2248
+ [data-effective-theme="dark"] .ba-actions select {
2222
2249
  background-image: var(--ba-select-arrow-dark);
2223
2250
  }
2224
2251
 
@@ -2591,7 +2618,8 @@ div.help ul {
2591
2618
  background-size: 0.65rem;
2592
2619
  }
2593
2620
 
2594
- [data-bs-theme="dark"] .ba-inline-table select {
2621
+ [data-bs-theme="dark"] .ba-inline-table select,
2622
+ [data-effective-theme="dark"] .ba-inline-table select {
2595
2623
  background-image: var(--ba-select-arrow-dark);
2596
2624
  }
2597
2625
 
@@ -2939,7 +2967,7 @@ body.login .ba-topbar-inner {
2939
2967
  padding: 2.5rem;
2940
2968
  border-radius: calc(var(--ba-radius) + 0.25rem);
2941
2969
  background:
2942
- radial-gradient(circle at 18% 18%, rgb(201 155 84 / 0.2), transparent 42%),
2970
+ radial-gradient(circle at 18% 18%, rgb(255 203 8 / 0.18), transparent 42%),
2943
2971
  var(--ba-topbar-bg);
2944
2972
  color: var(--ba-topbar-fg);
2945
2973
  box-shadow: var(--ba-shadow-lg);
@@ -2961,9 +2989,9 @@ body.login .ba-topbar-inner {
2961
2989
  place-items: center;
2962
2990
  width: 3rem;
2963
2991
  height: 3rem;
2964
- border-radius: 0.8rem;
2965
- background: #fff;
2966
- color: var(--ba-topbar-bg);
2992
+ border-radius: var(--ba-radius);
2993
+ background: var(--ba-gold);
2994
+ color: #231f20;
2967
2995
  font-size: 1.3rem;
2968
2996
  font-weight: 800;
2969
2997
  }
@@ -3390,6 +3418,15 @@ body.popup .ba-submit-row {
3390
3418
  padding-inline: 0.25rem;
3391
3419
  }
3392
3420
 
3421
+ .ba-view-site {
3422
+ width: 2.35rem;
3423
+ padding: 0;
3424
+ }
3425
+
3426
+ .ba-view-site-label {
3427
+ display: none;
3428
+ }
3429
+
3393
3430
  .ba-brand-title {
3394
3431
  max-width: 11rem;
3395
3432
  font-size: 0.9rem;
@@ -6,8 +6,8 @@
6
6
  <title>{% block title %}{% endblock %}</title>
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
8
  <meta name="color-scheme" content="light dark">
9
- <meta name="theme-color" content="#172b45" media="(prefers-color-scheme: light)">
10
- <meta name="theme-color" content="#0c1520" media="(prefers-color-scheme: dark)">
9
+ <meta name="theme-color" content="#231f20" media="(prefers-color-scheme: light)">
10
+ <meta name="theme-color" content="#242122" media="(prefers-color-scheme: dark)">
11
11
  <script src="{% static 'django_bootstrap6_admin/js/theme.js' %}" {% csp_nonce_attr %}></script>
12
12
  <link rel="stylesheet" href="{% static 'django_bootstrap6_admin/vendor/bootstrap/css/bootstrap.min.css' %}" {% csp_nonce_attr %}>
13
13
  <link rel="stylesheet" href="{% static 'admin/css/widgets.css' %}" {% csp_nonce_attr %}>
@@ -48,58 +48,60 @@
48
48
  </div>
49
49
 
50
50
  {% block usertools %}
51
- {% if has_permission %}
51
+ {% if site_url or has_permission %}
52
52
  <div id="user-tools" class="ba-user-tools">
53
- {% include "admin/color_theme_toggle.html" %}
54
- {% firstof user.get_short_name user.get_username as user_name %}
55
- <div class="ba-user-menu-wrap">
56
- <button type="button" class="btn btn-outline theme-secondary ba-user-menu-button"
57
- data-bs-toggle="menu" data-bs-target="#ba-user-menu"
58
- aria-expanded="false" aria-haspopup="true">
59
- <span class="visually-hidden">{% translate 'User menu' %}</span>
60
- <span class="ba-user-avatar" aria-hidden="true">{{ user_name|first|upper }}</span>
61
- <span class="ba-user-name">{% firstof user.get_short_name user.get_username %}</span>
62
- <svg class="ba-icon ba-chevron" aria-hidden="true"><use href="#ba-chevron-down"></use></svg>
63
- </button>
64
- <div class="menu ba-user-menu" id="ba-user-menu">
65
- {% block welcome-msg %}
66
- <div class="menu-header">
67
- {% translate 'Welcome,' %} <strong>{% firstof user.get_short_name user.get_username %}</strong>.
68
- </div>
69
- {% endblock %}
70
- {% block userlinks %}
71
- {% if site_url %}
72
- <a class="menu-item" href="{{ site_url }}">
73
- <svg class="ba-icon" aria-hidden="true"><use href="#ba-external"></use></svg>
74
- {% translate 'View site' %}
75
- </a>
76
- {% endif %}
77
- {% if user.is_active and user.is_staff %}
78
- {% url 'django-admindocs-docroot' as docsroot %}
79
- {% if docsroot %}
80
- <a class="menu-item" href="{{ docsroot }}">
81
- <svg class="ba-icon" aria-hidden="true"><use href="#ba-document"></use></svg>
82
- {% translate 'Documentation' %}
53
+ {% if site_url %}
54
+ <a class="btn btn-outline ba-view-site" href="{{ site_url }}">
55
+ <svg class="ba-icon" aria-hidden="true"><use href="#ba-external"></use></svg>
56
+ <span class="ba-view-site-label">{% translate 'View site' %}</span>
57
+ </a>
58
+ {% endif %}
59
+ {% if has_permission %}
60
+ {% include "admin/color_theme_toggle.html" %}
61
+ {% firstof user.get_short_name user.get_username as user_name %}
62
+ <div class="ba-user-menu-wrap">
63
+ <button type="button" class="btn btn-outline theme-secondary ba-user-menu-button"
64
+ data-bs-toggle="menu" data-bs-target="#ba-user-menu"
65
+ aria-expanded="false" aria-haspopup="true">
66
+ <span class="visually-hidden">{% translate 'User menu' %}</span>
67
+ <span class="ba-user-avatar" aria-hidden="true">{{ user_name|first|upper }}</span>
68
+ <span class="ba-user-name">{% firstof user.get_short_name user.get_username %}</span>
69
+ <svg class="ba-icon ba-chevron" aria-hidden="true"><use href="#ba-chevron-down"></use></svg>
70
+ </button>
71
+ <div class="menu ba-user-menu" id="ba-user-menu">
72
+ {% block welcome-msg %}
73
+ <div class="menu-header">
74
+ {% translate 'Welcome,' %} <strong>{% firstof user.get_short_name user.get_username %}</strong>.
75
+ </div>
76
+ {% endblock %}
77
+ {% block userlinks %}
78
+ {% if user.is_active and user.is_staff %}
79
+ {% url 'django-admindocs-docroot' as docsroot %}
80
+ {% if docsroot %}
81
+ <a class="menu-item" href="{{ docsroot }}">
82
+ <svg class="ba-icon" aria-hidden="true"><use href="#ba-document"></use></svg>
83
+ {% translate 'Documentation' %}
84
+ </a>
85
+ {% endif %}
86
+ {% endif %}
87
+ {% if user.has_usable_password %}
88
+ <a class="menu-item" href="{% url 'admin:password_change' %}">
89
+ <svg class="ba-icon" aria-hidden="true"><use href="#ba-key"></use></svg>
90
+ {% translate 'Change password' %}
83
91
  </a>
84
92
  {% endif %}
85
- {% endif %}
86
- {% if user.has_usable_password %}
87
- <a class="menu-item" href="{% url 'admin:password_change' %}">
88
- <svg class="ba-icon" aria-hidden="true"><use href="#ba-key"></use></svg>
89
- {% translate 'Change password' %}
90
- </a>
91
- {% endif %}
92
- <div class="menu-divider"></div>
93
- <form id="logout-form" method="post" action="{% url 'admin:logout' %}">
94
- {% csrf_token %}
95
- <button type="submit" class="menu-item">
96
- <svg class="ba-icon" aria-hidden="true"><use href="#ba-logout"></use></svg>
97
- {% translate 'Log out' %}
98
- </button>
99
- </form>
100
- {% endblock %}
93
+ <div class="menu-divider"></div>
94
+ <form id="logout-form" method="post" action="{% url 'admin:logout' %}">
95
+ {% csrf_token %}
96
+ <button type="submit" class="menu-item">
97
+ <svg class="ba-icon" aria-hidden="true"><use href="#ba-logout"></use></svg>
98
+ {% translate 'Log out' %}
99
+ </button>
100
+ </form>
101
+ {% endblock %}
102
+ </div>
101
103
  </div>
102
- </div>
104
+ {% endif %}
103
105
  </div>
104
106
  {% endif %}
105
107
  {% endblock %}
@@ -5,7 +5,6 @@
5
5
  {% block extrastyle %}{{ block.super }}{% csp_nonce_attr form.media %}{% endblock %}
6
6
  {% block bodyclass %}{{ block.super }} login ba-login-page ba-no-sidebar{% endblock %}
7
7
 
8
- {% block usertools %}{% endblock %}
9
8
  {% block nav-global %}{% endblock %}
10
9
  {% block nav-sidebar %}{% endblock %}
11
10
  {% block nav-breadcrumbs %}{% endblock %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-bootstrap6-admin
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A modern Bootstrap 6 skin for the Django admin.
5
5
  Author-email: Aliberk Sandıkçı <git@asandikci.com>
6
6
  Maintainer-email: Aliberk Sandıkçı <git@asandikci.com>
@@ -53,6 +53,7 @@ permissions and JavaScript remain in charge.
53
53
  ## Features
54
54
 
55
55
  - Bootstrap 6 markup and design tokens throughout the admin.
56
+ - "View site" is always available in the top bar, not buried in the user menu.
56
57
  - Sticky top bar with a collapsible sidebar (desktop) and drawer navigation
57
58
  with a backdrop (mobile).
58
59
  - Dashboard with application cards, model shortcuts and recent activity.
@@ -81,8 +82,8 @@ permissions and JavaScript remain in charge.
81
82
  - CSP-aware: bundled scripts and styles use Django 6.1's
82
83
  `{% csp_nonce_attr %}` tag, so nonce-based policies work out of the box.
83
84
  - Generic by design: no models, no migrations, no project-specific imports and
84
- no assumptions about the host project's branding. The default navy/gold
85
- palette is only a set of overridable CSS variables.
85
+ no assumptions about the host project's branding. The default warm
86
+ near-black/yellow palette is only a set of overridable CSS variables.
86
87
 
87
88
  ## Requirements
88
89
 
@@ -194,14 +195,15 @@ custom admin CSS file:
194
195
 
195
196
  ```css
196
197
  :root {
197
- --ba-topbar-bg: #1f2937;
198
- --ba-gold: #f59e0b;
198
+ --ba-topbar-bg: #231f20;
199
+ --ba-gold: #ffcb08;
200
+ --ba-canvas: #f6f6f4;
199
201
  --ba-sidebar-width: 300px;
200
202
  }
201
203
  ```
202
204
 
203
- The default primary and danger colours are deliberately deeper than Bootstrap
204
- 6's defaults so white button text meets WCAG AA contrast.
205
+ The default primary is the warm yellow accent with dark text, and the danger
206
+ colour remains a deep red for readable white labels.
205
207
 
206
208
  The select controls use small `data:` SVG arrows. If you enable a strict CSP,
207
209
  allow `img-src 'self' data:` (or replace the arrows in your own CSS).
@@ -229,6 +231,16 @@ There is no runtime state to clean up.
229
231
  - `bootstrap.bundle.min.js`:
230
232
  `47ea447f46e288dd9d3e83147b7ba539c6df5192c047b8f91739cd56a5721148`
231
233
 
234
+ ### Language
235
+
236
+ Django's admin is translated using the active language; it is not fixed to
237
+ English. With `LANGUAGE_CODE = "tr"`, Django's own admin labels are Turkish,
238
+ and this theme follows the same project language. The package's source strings
239
+ are English and are translated when a matching locale is installed. To keep
240
+ the admin in English while the public site uses another language, activate
241
+ English for `/admin/` in your project (for example with a small middleware),
242
+ or set `LANGUAGE_CODE = "en-us"` if the whole site should be English.
243
+
232
244
  ## Development
233
245
 
234
246
  The test suite uses an isolated settings module and a small demo app. Create a
@@ -49,6 +49,7 @@ class AdminUiTests(TestCase):
49
49
  self.assertContains(response, "ba-app-grid")
50
50
  self.assertContains(response, "ba-recent-card")
51
51
  self.assertContains(response, "theme-toggle")
52
+ self.assertContains(response, "ba-view-site")
52
53
 
53
54
  def test_default_django_admin_css_is_not_loaded(self):
54
55
  response = self.client.get(reverse("admin:index"))
@@ -222,6 +223,7 @@ class AdminUiTests(TestCase):
222
223
  self.assertContains(response, 'type="password"')
223
224
  self.assertContains(response, "theme-toggle")
224
225
  self.assertContains(response, "ba-login")
226
+ self.assertContains(response, "ba-view-site")
225
227
 
226
228
  def test_login_post_works(self):
227
229
  self.client.logout()
@@ -61,4 +61,6 @@ class PackageAssetsTests(SimpleTestCase):
61
61
  self.assertIn("ba-filters-collapsed", admin_css)
62
62
  self.assertIn("border-inline-end: 1px solid var(--bs-border-muted)", admin_css)
63
63
  self.assertIn("appearance: none", admin_css)
64
- self.assertIn("--bs-fg-4: #9fb1c4", admin_css)
64
+ self.assertIn("--bs-fg-4: #b0aaa9", admin_css)
65
+ self.assertIn("--ba-topbar-bg: light-dark(#231f20, #242122)", admin_css)
66
+ self.assertIn("--bs-primary-bg: light-dark(#ffcb08, #d8ab32)", admin_css)