Scaffold the mobile member app: PWA shell, push, and app-shell tokens

New `mobile` Django app mounted at /app/ -- the installed PWA for Member
mode (M1-M7, see design_handoff_rosterchief_platform/README.md). Coach
mode (C1-C6) is a later phase and has no routes yet.

Foundation pieces:
- assets/mobile.css: Tailwind v4 theme reusing management.css's design
  tokens (same per-club --tenant-* theming pattern), plus the ice/coach
  accent and mobile's 14px card radius.
- PushSubscription model + pywebpush-based sender (mobile/services/push.py),
  wired to notifications.Notification via a post_save signal so the
  existing notification system gains a push channel without knowing about
  PWAs itself.
- Per-club manifest.webmanifest + service worker (served at /app/sw.js)
  + a server-rendered fallback home-screen icon (club initials on
  secondary_color) for clubs without an uploaded logo -- confirmed with
  the user as the fallback, never a generic RosterChief mark.
- App shell (base.html): navy header, person switcher (every child a
  signed-in parent manages, plus "Me"), bottom tab bar, safe-area insets.
  Vendored htmx + Alpine for the screens built on top of it.
- Placeholder views/routes for all seven M1-M7 screens so the shell is
  fully wired end-to-end before each screen is built out individually.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
2026-08-21 10:27:13 +02:00
parent 0ecdeac354
commit 09df5d25b8
29 changed files with 1657 additions and 6 deletions

View File

@@ -2774,6 +2774,9 @@
.right-0 {
right: 0;
}
.right-1\.5 {
right: calc(var(--spacing) * 1.5);
}
.right-2 {
right: calc(var(--spacing) * 2);
}
@@ -3853,6 +3856,9 @@
.h-1\.5 {
height: calc(var(--spacing) * 1.5);
}
.h-2 {
height: calc(var(--spacing) * 2);
}
.h-4 {
height: calc(var(--spacing) * 4);
}
@@ -3967,6 +3973,9 @@
.w-1\.5 {
width: calc(var(--spacing) * 1.5);
}
.w-2 {
width: calc(var(--spacing) * 2);
}
.w-4 {
width: calc(var(--spacing) * 4);
}
@@ -4741,6 +4750,9 @@
.pt-4 {
padding-top: calc(var(--spacing) * 4);
}
.pb-0\.5 {
padding-bottom: calc(var(--spacing) * 0.5);
}
.pb-2 {
padding-bottom: calc(var(--spacing) * 2);
}
@@ -4858,6 +4870,9 @@
.text-\[17px\] {
font-size: 17px;
}
.text-\[19px\] {
font-size: 19px;
}
.text-\[22px\] {
font-size: 22px;
}
@@ -5260,6 +5275,13 @@
--btn-soft-bg: initial;
}
}
.btn-secondary {
@layer daisyui.l1.l2 {
--btn-color: var(--color-secondary);
--btn-fg: var(--color-secondary-content);
--btn-soft-bg: initial;
}
}
.btn-sm {
@layer daisyui.l1.l2 {
--fontsize: 0.75rem;

2
static/css/mobile.css Normal file

File diff suppressed because one or more lines are too long